我想专门为某个 GUID 设计一个模板,它是一个 16 字节的结构。GUID 对象有内部链接,所以我不能使用对象本身的地址,但我认为我可以使用对象的内容,因为对象是一个常量。但这不起作用,如此示例代码所示:
struct S
{
int const i;
};
S const s = { 42 };
char arr[s.i];
如果 s 是常数,为什么 si 不是常数?任何解决方法?
结构的初始化s
可以在运行时发生。但是,数组的大小必须在编译时知道。编译器不会(肯定)知道 的值s.i
在编译时是已知的,所以它只是看到你正在使用一个你不应该使用的变量。问题不在于常量,而是何时需要数组大小的问题。
你可能误解了什么const
意思。这只意味着变量初始化后,永远不会改变。例如这是合法的:
void func(int x){
const int i = x*5; //can't be known at compile-time, but still const
//int array[i]; //<-- this would be illegal even though i is const
}
int main(){
int i;
std::cin >> i;
func(i);
return 0;
}
为了绕过这个限制,在 C++11 中,您可以将其标记为constexpr
指示该值可以在编译时确定。这似乎是你想要的。
struct S
{
int const i;
};
int main(){
constexpr S const s = { 42 };
char arr[s.i];
return 0;
}
编译:
$ c++ -std=c++11 -pedantic file.cpp
在 C99 中,您所做的是合法的,数组的大小不需要在编译时知道。
struct S
{
int const i;
};
int main(){
struct S const s = { 42 };
char arr[s.i];
return 0;
}
编译:
$ cc -std=c99 -pedantic file.c
至少在大多数情况下,const
实际上意味着更接近“只读”而不是“常量”。在 C89/90 中,它基本上意味着“只读”。C++ 增加了一些它可以保持不变的情况,但它仍然没有接近所有时间(不幸的是,在不平凡的情况下准确跟踪它的含义)。
幸运的是,“解决方法”是以几乎可以肯定在任何情况下都应该的方式编写代码:
std::vector<char> arr(s.i);
底线:C++ 中内置数组的大多数使用都应该被认为是可疑的。您可以从非常量表达式初始化向量这一事实只是众多优势之一。