众所周知,必须确定C++中的数组长度.然后我们可以使用:
const int MAX_Length=100;
Run Code Online (Sandbox Code Playgroud)
要么:
#define MAX_LENGTH 100
Run Code Online (Sandbox Code Playgroud)
在编译之前确定数组的长度.但是,当我读到lippman的书c ++入门时,在第5版的第3.5.1节中,它说:数组的长度必须是一个常量表达式.然后问题来了:
typedef enum Length{LEN1=100, LEN2, LEN3, LEN4}LEN;
LEN MAX_Length=LEN2; //101
int iArray[LEN2]; //attention
Run Code Online (Sandbox Code Playgroud)
代码在mingw32-g ++中成功编译.但在VS2008中失败了,错误是:
error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'iArray' : unknown size
Run Code Online (Sandbox Code Playgroud)
我认为枚举值是常量,因此它应该用作数组的长度.对?
我很困惑,你能帮助我吗?谢谢.
在对另一个问题的评论中,用户hvd声明了以下内容:
...虽然字符串文字可以传递给
constexpr函数,并且在常量表达式中的字符串文字上允许数组索引,但constexpr函数参数的索引操作不符合常量表达式.
我并不完全明白这是什么意思.这是否意味着hash_value以下代码中的变量
#include <cstddef>
// Compute the hash of a string literal adding the values of its characters
template<std::size_t N> constexpr std::size_t
hash_string
( const char (& s)[N] )
noexcept
{
std::size_t h = 0;
// Array indexing happening under the hood
for ( const auto c : s )
h += c;
return h;
}
constexpr auto hash_value = hash_string("Hello, world!");
Run Code Online (Sandbox Code Playgroud)
无法在编译时进行评估?你能详细说明引用的评论并告诉我是否正确吗?
在阅读了Martin Uecker 谓词的标准 C11 版本后ICE_P,我尝试用纯 C++ 实现它。C11版本,使用_Generic选择如下:
#define ICE_P(x) _Generic((1? (void *) ((x)*0) : (int *) 0), int*: 1, void*: 0)
Run Code Online (Sandbox Code Playgroud)
C++ 的明显方法是_Generic用模板 和替换decltype,例如:
template<typename T> struct is_ice_helper;
template<> struct is_ice_helper<void*> { enum { value = false }; };
template<> struct is_ice_helper<int*> { enum { value = true }; };
#define ICE_P(x) (is_ice_helper<decltype(1? (void *) ((x)*0) : (int *) 0)>::value)
Run Code Online (Sandbox Code Playgroud)
然而,它未能通过最简单的测试。为什么它不能检测整数常量表达式?
如果使用 gcc v10 编译,下面的代码会出现错误,但对于 gcc v9,代码没问题。
template<auto N>
struct A {
constexpr auto size() const {
return N;
}
};
template<typename T>
void foo1(const T& a) {
constexpr auto s = a.size(); // Why error here?
}
template<typename T>
void foo2(T a) {
constexpr auto s = a.size(); // OK
}
int main() {
A<10> x1;
foo1(x1);
foo2(x1);
A<x1.size()> x2; // OK
constexpr auto s = x1.size(); // OK
}
Run Code Online (Sandbox Code Playgroud)
在我的理解中,成员函数 size() 在所有情况下都可以称为 constexpr。但是在一种情况下,与 gcc9 相比,gcc10 的行为发生了变化:如果参数由 const-ref 传递。我不明白为什么这不应该是 constexpr? …
这个问题的动机是这个。
考虑以下代码:
struct B {};
struct S {
B b; // #1
S() = default;
template <typename ...dummy> // #2
constexpr S(const S&) {}
template <typename ...dummy> // #3
constexpr S(S &other)
: S(const_cast<const S&>(other)) // #4
{}
};
S s;
constexpr S f() {return s;}
int main() {
constexpr auto x = f();
}
Run Code Online (Sandbox Code Playgroud)
GCC 成功编译了这段代码,但 Clang 拒绝了它(Godbolt.org 上的示例)。Clang 产生的错误信息是
<source>:21:20: error: constexpr variable 'x' must be initialized by a constant expression
constexpr auto x …Run Code Online (Sandbox Code Playgroud) c++ templates copy-constructor language-lawyer constant-expression
我遇到了以下代码不起作用的问题。我在Java SE 11 (11.0.8)、Eclipse 2020-06、Windows 10 中运行了代码。
将字符串最终变量与三元运算符一起使用:不起作用
public class Tester {
public static void main(String[] args) {
String switchVar = "abc";
final String caseStr = true ? "abc" : "def";
switch (switchVar) {
case caseStr: System.out.println("Doesn't work");
}
}
}
Run Code Online (Sandbox Code Playgroud)
它有一个编译时错误:java.lang.Error: Unresolved compilation problem: case expressions must be constant expressions。
但是,根据JLS §4.12.4和JLS §15.28,String 类型可以是最终变量,三元运算符也可以算作常量表达式。
常量变量是用常量表达式初始化的原始类型或字符串类型的最终变量。
常量表达式是表示原始类型的值或不会突然完成并且仅使用以下内容组成的字符串的表达式:
...
三元条件运算符 ? :
引用常量变量的简单名称
我做了一些更多的测试,结果表明如果不结合在一起,这些点中的任何一个都可以工作。
直接使用常量表达式作为 case 常量:没问题
public …Run Code Online (Sandbox Code Playgroud) 当我编译以下代码片段时:
struct Packet([u8; 4]);
impl Packet {
const fn from(labels: [&[u8; 2]; 2]) -> Packet {
let mut bytes = [0; 4];
bytes[..2].copy_from_slice(labels[0]);
bytes[2..].copy_from_slice(labels[1]);
Packet(bytes)
}
}
const AA: &[u8; 2] = b"AA";
const BB: &[u8; 2] = b"BB";
const CC: &[u8; 2] = b"CC";
const AABB: Packet = Packet::from([AA, BB]);
const AACC: Packet = Packet::from([AA, CC]);
Run Code Online (Sandbox Code Playgroud)
我收到以下编译器错误:
error[E0723]: mutable references in const fn are unstable
--> src/main.rs:7:9
|
7 | bytes[..2].copy_from_slice(labels[0]);
| ^^^^^^^^^^
|
= note: see issue #57563 …Run Code Online (Sandbox Code Playgroud) 澄清一下,以下程序格式是否正确?
#include <new>
char foo[32];
struct bar {
static constexpr int foobar = 42;
};
int main()
{
auto p = new (foo) bar();
static_assert(p->foobar == 42);
}
Run Code Online (Sandbox Code Playgroud)
gcc和msvc接受,但clang因错误而拒绝
read of non-constexpr variable 'p' is not allowed in a constant expression,谁是对的?
c++ static-members placement-new language-lawyer constant-expression
我一直试图了解静态变量是如何初始化的。并注意到cppref和 enseignement处常量初始化和零初始化的顺序存在矛盾。
在cppref上它说:
常量初始化是在所有其他初始化之前执行的,而不是静态和线程局部(C++11 起)对象的零初始化。
而在enseignement中它说:
常量初始化是在静态和线程局部对象的零初始化之后以及所有其他初始化之前执行的。
正如您所看到的,cppref 使用“instead”,而第二个站点使用“after”。两者哪个是正确的?也就是说,零初始化是否总是首先发生,然后如果可能的话,如第二个站点所暗示的那样进行常量初始化,或者反之亦然。
那里给出的例子如下:
#include <iostream>
#include <array>
struct S {
static const int c;
};
const int d = 10 * S::c; // not a constant expression: S::c has no preceding
// initializer, this initialization happens after const
const int S::c = 5; // constant initialization, guaranteed to happen first
int main()
{
std::cout << "d = " << …Run Code Online (Sandbox Code Playgroud) c++ initialization compile-time-constant constant-expression c++11
我已经了解了constexprC++ 中的变量,并阅读了int i =0; constexpr int j = i;失败的内容,因为i它不是有意义的常量表达式。但是当我对类的变量做同样的事情时,它起作用了。
struct C{};
int main()
{
int i = 0; //i is not a constant expression as expected
//constexpr int j = i; //this fails AS EXPECTED
C c;
constexpr C d = c; //WHY DOESN'T THIS FAIL??
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,constexpr C d = c;编译没有任何问题,不像constexpr int j = i;即使c也不是常量表达式。
我想知道这背后的原因。