没有数据成员和大括号语法的 class 的默认复制构造函数
Default copy constructor for a class without data members and brace syntax
考虑以下 class 定义:
class A { };
也就是说,A
是一个没有 数据成员 的 class(即使它没有 函数成员)。
以下代码按预期工作,因为编译器为 class A
:
A foo;
A bar(foo); // calls A's default copy constructor
但是,如果使用 大括号语法 而不是括号。代码无法编译:
A foo;
A bar{foo}; // ERROR
在 GCC 4.9.3 上我得到错误:
too many initializers for 'A'
通过执行以下任一操作,最后一个代码片段可以正常工作:
- 将 数据成员 添加到
A
class 定义。
- 在
A
class 定义中显式定义一个 复制构造函数 (即使使用 = default
也行不通)。当然,默认构造函数也必须在这样做之后定义上面的代码才能工作,因为它不再由编译器生成。
知道为什么会这样吗?
您可以在使用 gcc 5.1 时编译此示例,但只能在使用 c++14 时进行编译,您可以使用 -std=c++14 标志启用它。
正在查看http://en.cppreference.com/w/cpp/language/aggregate_initialization
你可以在例子中看到:
S s1 = { 1, { 2, 3, {4, 5, 6} } };
S s2 = { 1, 2, 3, 4, 5, 6}; // same, but with brace elision
S s3{1, {2, 3, {4, 5, 6} } }; // same, using direct-list-initialization syntax
S s4{1, 2, 3, 4, 5, 6}; // error in C++11: brace-elision only allowed with equals sign
// okay in C++14
所以这似乎是 c++14 的特性。
正如 Zereges 在他的评论中所暗示的那样,代码无法编译的问题是 GCC 中的一个 bug。
此错误已在 GCC 6.1 版中修复,代码按预期编译。
考虑以下 class 定义:
class A { };
也就是说,A
是一个没有 数据成员 的 class(即使它没有 函数成员)。
以下代码按预期工作,因为编译器为 class A
:
A foo;
A bar(foo); // calls A's default copy constructor
但是,如果使用 大括号语法 而不是括号。代码无法编译:
A foo;
A bar{foo}; // ERROR
在 GCC 4.9.3 上我得到错误:
too many initializers for 'A'
通过执行以下任一操作,最后一个代码片段可以正常工作:
- 将 数据成员 添加到
A
class 定义。 - 在
A
class 定义中显式定义一个 复制构造函数 (即使使用= default
也行不通)。当然,默认构造函数也必须在这样做之后定义上面的代码才能工作,因为它不再由编译器生成。
知道为什么会这样吗?
您可以在使用 gcc 5.1 时编译此示例,但只能在使用 c++14 时进行编译,您可以使用 -std=c++14 标志启用它。
正在查看http://en.cppreference.com/w/cpp/language/aggregate_initialization 你可以在例子中看到:
S s1 = { 1, { 2, 3, {4, 5, 6} } };
S s2 = { 1, 2, 3, 4, 5, 6}; // same, but with brace elision
S s3{1, {2, 3, {4, 5, 6} } }; // same, using direct-list-initialization syntax
S s4{1, 2, 3, 4, 5, 6}; // error in C++11: brace-elision only allowed with equals sign
// okay in C++14
所以这似乎是 c++14 的特性。
正如 Zereges 在他的评论中所暗示的那样,代码无法编译的问题是 GCC 中的一个 bug。
此错误已在 GCC 6.1 版中修复,代码按预期编译。