[英]defining destructor in a class derived from move-only type gives compile-time error when created with emplace_back or push_back of std::vector
[英]std::list of move-only type: Cannot emplace into std::vector in VC++
在VC ++ 2019中,我不能emplace_back
一个只移动类型的(右值) list
。
#include <vector>
#include <list>
struct A
{
A(A&&) {}
};
using ListOfA = std::list<A>;
int main()
{
std::vector<ListOfA> v;
// Build error in VC++ 2019
// No error in Clang and GCC C++11 - C++2a
v.emplace_back(std::move(ListOfA()));
}
尝试在VC ++ 2019中构建时会出现以下编译错误:
'A::A(const A &)': attempting to reference a deleted function
显然,VC ++试图实例化(左值)拷贝构造函数的A
,它(正确地)不存在,因为我已经明确定义构造函数的一个A
。
我认为通过从另一个list
移动来在vector
就地实例化list
应该是有效的 - 也就是说, list
类确实有一个移动构造函数 ,我认为这应该只是让新list
取得所有权(移动) list
的元素,无需任何副本。
事实上,使用Wandbox,使用GCC和Clang 构建和运行相同的代码时没有错误 。
有人可以解释为什么这段代码不能在VC ++ 2019中编译? 我是否有误解 - 实际上是否有正确的理由为什么(左值)复制构造函数在上面的代码中由VC ++编译器实例化?
注意
当std::move(...)
不存在时,VC ++中会出现同样的错误; 即此行发生相同的错误:
v.emplace_back(ListOfA());
MSVC使用std::list
的复制构造函数,因为它的移动构造函数正在抛出。 在重新分配期间,如果移动构造函数抛出,则std::vector
无法提供标准所要求的强异常保证。
在您的情况下,向量在重新分配之前没有任何元素,因此看起来没有调用复制构造函数,但这并不意味着不需要复制构造函数。
libstdc ++中的std::list
和libc ++有noexcept
移动构造函数。 这是允许的,但标准不要求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.