Rya*_*ing 9 c++ copy-constructor uniform-initialization c++11
在更新一些代码以使用统一初始化时,我认为它将成为现在"旧式"括号样式的现代替代品.我知道情况并非总是如此(显而易见的例子vector<int>),但我偶然发现了另一个我不理解的差异.
class Object {
public:
Object() = default;
Object(const Object&) = default;
};
int main() {
Object o;
Object copy{o}; // error
Object copy2(o); // OK
}
Run Code Online (Sandbox Code Playgroud)
无法在clang3.5下编译并出现错误:(在gcc下也失败)
error: excess elements in struct initializer
Run Code Online (Sandbox Code Playgroud)
这有两个不同的变化Object使这项工作.向其添加数据成员,或为其提供空复制构造函数体
class Object {
private:
int i; // this fixes it
public:
Object() = default;
Object(const Object&) { } // and/or this fixes it as well
};
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这些应该有所作为.
这是一个已知的错误,希望在C++ 17中修复(不适用于C++ 14,请参阅http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1467) .您的结构是一个聚合,因此要初始化它{someElement}需要至少有一个数据成员,如您所发现的那样.尝试提供一个operator int();,你会看到它编译.
约翰内斯的回答很有用,但让我详细说明一下为什么会发生这种情况。
\n\n您描述的这两个更改都会影响您的类,使其从聚合变为非聚合。请参阅 C++11 (N3485) \xc2\xa7 8.5.1/1:
\n\n\n\n\n聚合是一个数组或类(第 9 条),没有用户提供的构造函数 (12.1),没有非静态数据成员的大括号或等于初始化器(9.2),没有私有或受保护的非静态数据成员 (第 11 条),没有基类(第 10 条),也没有虚函数(10.3)。
\n
定义为 的构造函数= default被视为不是用户定义的。
然后,进入 \xc2\xa7 8.5.4 中的列表初始化,我们看到:
\n\n\n\n\nT 类型的对象或引用的列表初始化定义如下:
\n\n\n
\n- 如果T是聚合,则执行聚合初始化
\n
然后是一堆“否则……”部分。因此,更改其中任何一个都允许调用构造函数而不是执行聚合初始化。
\n\n新提议的列表初始化定义标准(如约翰内斯的链接中所示)提供了列表中单个元素的优先级情况,并且它具有(或非常接近)对象类型的类型已初始化。之后聚合初始化将是最优先的。
\n| 归档时间: |
|
| 查看次数: |
319 次 |
| 最近记录: |