Kyl*_*and 2 c++ move-semantics c++11 c++14 c++17
给出以下代码段:
class Foo {};
Foo makeFoo() { return Foo{}; }
int main()
{
Foo myFoo{makeFoo()};
}
Run Code Online (Sandbox Code Playgroud)
我希望单行输入使用's move构造函数的返回值main
来声明和定义/初始化.myFoo
Foo
makeFoo()
但是,我从clang++
3.5.1(在C++ 14模式下编译)得到以下错误:
error: excess elements in struct initializer
Foo myFoo{makeFoo()};
^~~~~~~~~
1 error generated.
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?"struct initializer"究竟意味着什么 - 它只是POD的默认(无参数)构造函数吗?为什么不调用移动构造函数?
毕竟,没有"通用(或统一)初始化语法"这样的东西.列表初始化有一些特殊的行为.
在您的情况下,相关规则见8.5.1节:
聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚函数(10.3) ).
class Foo
因此,您是一个聚合.
当初始化程序列表初始化聚合时,如8.5.4中所述,初始化程序列表的元素将作为聚合成员的初始化程序,增加下标或成员顺序.每个成员都是从相应的initializer子句复制初始化的.如果initializer子句是表达式并且转换表达式需要缩小转换(8.5.4),则程序格式错误.
这就是编译器解释你的代码的方式(正如@chris所说,在下一个版本的C++中,它不会这样做......虽然我认为这个规则也需要更新,但仅仅是" 8.5.4"实际上不足以停止聚合初始化行为".
由于初始化程序比成员多,因此是非法的.
作为类的聚合也可以使用未括在大括号中的单个表达式进行初始化,如8.5中所述.
这是允许复制/移动初始化的规则.复制/移动聚合不能使用大括号.
归档时间: |
|
查看次数: |
385 次 |
最近记录: |