考虑一下守则:
struct Foo
{
const char str[] = "test";
};
int main()
{
Foo foo;
}
它不能同时使用g++和clang++进行编译,本质上是抛出的。
error: array bound cannot be deduced from an in-class initializer
我知道标准可能是这么说的,但有什么特别好的理由吗?因为我们有一个字符串文本,所以编译器似乎应该能够在没有任何问题的情况下推断出字符串的大小,类似于您只需要声明一个类外const
C类的空终止字符串时的情况。
发布于 2015-04-12 18:55:59
原因是,您始终有可能重写构造函数中的类内初始化程序列表。所以我想到最后,这可能会很令人困惑。
struct Foo
{
Foo() {} // str = "test\0";
// Implementing this is easier if I can clearly see how big `str` is,
Foo() : str({'a','b', 'c', 'd'}) {} // str = "abcd0"
const char str[] = "test";
};
请注意,用const char
替换static constexpr char
非常有效,而且可能无论如何都是您想要的。
发布于 2015-04-12 19:27:41
正如评论中提到的那样,正如@sbabbi所回答的,答案在于细节。
12.6.2初始化基和成员class.base.init
- if the entity is a non-static data member that has a brace-or-equal-initializer , the entity is initialized as specified in 8.5;
- otherwise, if the entity is an anonymous union or a variant member (9.5), no initialization is performed;
- otherwise, the entity is default-initialized
12.6.2初始化基和成员class.base.init
A(int)构造函数将简单地将I初始化为arg的值,并且I的支撑--或相等--初始化器中的副作用不会发生。-最终例子]
因此,如果存在不删除构造函数,则忽略大括号或等初始化项,而成员中的构造函数将占上风。因此,对于省略了大小的数组成员,表达式就会出现格式错误.§12.6.2第9项更明确地说明,如果构造函数执行mem-初始化,r值初始化器表达式将被省略。
此外,谷歌集团的讨论C++中另一个不协调的行为,进一步阐述和使它更加清晰。它扩展了解释大括号或相等初始化器是在成员的内部初始化不存在的情况下的成员内部初始化的一种光荣方式的概念。作为一个例子
struct Foo {
int i[5] ={1,2,3,4,5};
int j;
Foo(): j(0) {};
}
等于
struct Foo {
int i[5];
int j;
Foo(): j(0), i{1,2,3,4,5} {};
}
但现在我们看到,如果省略数组大小,则表达式的格式将不正确。
但是,如果成员不是由成员内构造函数初始化初始化的,但是为了统一起见,编译器本来可以支持这个特性,但是与其他许多事情一样,标准也不支持这个特性。
发布于 2015-04-12 18:56:44
如果允许编译器支持您所描述的内容,并且将str
的大小推断为5
,
Foo foo = {{"This is not a test"}};
会导致未定义的行为。
https://stackoverflow.com/questions/29593207
复制相似问题