我们知道这T v(x);被称为直接初始化,而T v = x;被称为复制初始化,这意味着它将构造一个临时T的x,将被复制/移入v(很可能被省略).
对于列表初始化,标准根据上下文区分两种形式.T v{x};称为直接列表初始化,T v = {x};称为复制列表初始化:
§8.5.4 [dcl.init.list] p1
[...]列表初始化可以在直接初始化或复制初始化上下文中进行; 直接初始化上下文中的列表初始化称为直接列表初始化,复制初始化上下文中的列表初始化称为复制列表初始化.[...]
但是,整个标准中只有两个引用.对于直接列表初始化,在创建像T{x}(§5.2.3/3)这样的临时表时会提到它.对于copy-list-initialization,它用于返回语句中的表达式,如return {x};(§6.6.3/2).
现在,下面的片段怎么样?
#include <initializer_list>
struct X{
X(X const&) = delete; // no copy
X(X&&) = delete; // no move
X(std::initializer_list<int>){} // only list-init from 'int's
}; …Run Code Online (Sandbox Code Playgroud) 在C++ 03中,不可能通过值返回具有私有非定义复制构造函数的类的对象:
struct A { A(int x) { ... } private: A(A const&); };
A f() {
return A(10); // error!
return 10; // error too!
}
Run Code Online (Sandbox Code Playgroud)
我想知道,这个限制是否在C++ 11中解除了,是否可以编写具有类类型返回类型的函数,而没有用于复制或移动的构造函数?我记得允许函数的调用者使用新返回的对象可能很有用,但是他们无法复制值并将其存储在某处.
g ++ 4.7支持数组成员初始化,我开始玩它.
下面的代码无法编译.
struct A
{
A(int){};
A(const A&) = delete;
A& operator=(const A&) = delete;
~A(){};
};
struct B
{
B():
a{{0},{1}}
{};
A a[2];
};
B b;
Run Code Online (Sandbox Code Playgroud)
gcc 4.8(预发布)的错误消息是:
n.cc: In constructor ‘B::B()’:
n.cc:12:20: error: use of deleted function ‘A::A(const A&)’
a{{0},{1}}
^
n.cc:4:8: error: declared here
A(const A&) = delete;
^
Run Code Online (Sandbox Code Playgroud)
有没有办法让这段代码有效?我不能轻易地改变A的构造函数,析构函数.我似乎需要一个move-constructor或copy-constructor来初始化数组,但这似乎是违反直觉的,因为我真正想要的就是就地构造.
如果我在2个成员a0和a1中分割[2]并分别构造它们,它就可以工作.然而,这看起来很可疑.