我有以下非常简单的课程:
class Foo
{
public:
Foo() {}
Foo(const Foo&) = delete;
Foo(Foo&&) {}
void operator=(const Foo&) = delete;
void operator=(Foo&&) {}
void dump() const {}
};
该类是可移动构造和可分配的,但不可复制构造和可分配的。
我想使用向量的初始化列表来初始化 Foo 元素的向量。
std::vector<Foo> vf = { Foo() };
编译器会抱怨,因为代码必须使用已删除的复制构造函数。有人可以解释一下,为什么在这种情况下不使用移动构造,以及为什么需要对象的副本?
以下还需要复制构造函数,但也不起作用:
std::vector<Foo> vf = { std::move(Foo()) };
另一方面,这工作正常(调用移动构造函数):
std::vector<Foo> vf;
vf.push_back(Foo());
感谢您的解释... :)
Update:
一个建议this https://stackoverflow.com/questions/8193102/initializer-list-and-move-semantics帖子解释了我的问题。
此外,让我们考虑以下代码(连同class Foo
above):
class Bar {
public:
Bar(std::initializer_list<Foo> _l) {
std::cout << "Bar::Bar()" << std::endl;
for (auto& e : _l)
e.dump();
}
};
int main() {
Bar b { Foo() };
return 0;
}
这会产生以下输出(用 C++11 编译):
Foo::Foo()
Bar::Bar()
Foo::dump()
Foo::~Foo()
可以看出,初始化列表实际上并未填充大括号之间声明的“对象的副本”。对于 C++14 来说,这可能不是真的。