为什么 vector<T>::emplace_back,使得 T 有一个被删除的复制构造函数,编译失败?
Why does vector<T>::emplace_back, such that T has a deleted copy constructor, fail to compile?
我无法编译以下 dont_compile
函数。我不明白为什么它不起作用。但是,它确实适用于 list
.
class Thing {
public:
Thing() {}
Thing(const Thing &) = delete;
};
int dont_compile(int argc, char ** argv)
{
std::vector<Thing> v;
v.emplace_back();
return 0;
}
int compiles(int argc, char ** argv)
{
std::list<Thing> v;
v.emplace_back();
return 0;
}
这是编译器的错误。这是一个错误吗?
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1752:31: error: call to deleted constructor of 'Thing'
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
... snip ...
note: 'Thing' has been explicitly marked deleted here
Thing(const Thing &) = delete;
我真的不明白 _Up(...)
是如何导致调用复制构造函数的。
std::vector::emplace_back
要求向量类型为 EmplaceConstructible
以及 MoveInsertable
。由于你删除了复制构造函数并且没有自己定义移动构造函数,所以 Thing
不满足第二个要求。相比之下,std::list::emplace_back
只要求list类型为EmplaceConstructible
.
当你有移动构造函数时它有效:
#include <vector>
class Thing {
public:
Thing() {}
Thing(const Thing &) = delete;
Thing(Thing&&) = default;
};
int main() {
std::vector<Thing> v;
v.emplace_back();
return 0;
}
std::vector::emplace_back
的类型要求可以提供更多信息。
我无法编译以下 dont_compile
函数。我不明白为什么它不起作用。但是,它确实适用于 list
.
class Thing {
public:
Thing() {}
Thing(const Thing &) = delete;
};
int dont_compile(int argc, char ** argv)
{
std::vector<Thing> v;
v.emplace_back();
return 0;
}
int compiles(int argc, char ** argv)
{
std::list<Thing> v;
v.emplace_back();
return 0;
}
这是编译器的错误。这是一个错误吗?
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1752:31: error: call to deleted constructor of 'Thing'
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
... snip ...
note: 'Thing' has been explicitly marked deleted here
Thing(const Thing &) = delete;
我真的不明白 _Up(...)
是如何导致调用复制构造函数的。
std::vector::emplace_back
要求向量类型为 EmplaceConstructible
以及 MoveInsertable
。由于你删除了复制构造函数并且没有自己定义移动构造函数,所以 Thing
不满足第二个要求。相比之下,std::list::emplace_back
只要求list类型为EmplaceConstructible
.
当你有移动构造函数时它有效:
#include <vector>
class Thing {
public:
Thing() {}
Thing(const Thing &) = delete;
Thing(Thing&&) = default;
};
int main() {
std::vector<Thing> v;
v.emplace_back();
return 0;
}
std::vector::emplace_back
的类型要求可以提供更多信息。