[英]std::list of move-only type: Cannot emplace into std::vector in VC++
In VC++ 2019, I cannot emplace_back
an (rvalue) list
of a move-only type. 在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()));
}
Attempting to build in VC++ 2019 gives the following compile error: 尝试在VC ++ 2019中构建时会出现以下编译错误:
'A::A(const A &)': attempting to reference a deleted function
Clearly, VC++ is attempting to instantiate the (lvalue) copy constructor for A
, which (correctly) does not exist because I have explicitly defined one of the constructors for A
. 显然,VC ++试图实例化(左值)拷贝构造函数的
A
,它(正确地)不存在,因为我已经明确定义构造函数的一个A
。
I would think that it should be valid to instantiate a list
in-place in a vector
by moving from another list
- that is, the list
class does have a move constructor which I'd think should simply cause the new list
to take ownership over the elements in the (moved-from) list
, without requiring any copies. 我认为通过从另一个
list
移动来在vector
就地实例化list
应该是有效的 - 也就是说, list
类确实有一个移动构造函数 ,我认为这应该只是让新list
取得所有权(移动) list
的元素,无需任何副本。
In fact, using Wandbox, the same code builds and runs without error using GCC and Clang. 事实上,使用Wandbox,使用GCC和Clang 构建和运行相同的代码时没有错误 。
Can somebody explain why this code does not compile in VC++ 2019? 有人可以解释为什么这段代码不能在VC ++ 2019中编译? Do I have a misunderstanding - is there in fact a valid reason why the (lvalue) copy constructor is being instantiated by the VC++ compiler in the code above?
我是否有误解 - 实际上是否有正确的理由为什么(左值)复制构造函数在上面的代码中由VC ++编译器实例化?
Note 注意
The same error occurs in VC++ when the std::move(...)
is not present; 当
std::move(...)
不存在时,VC ++中会出现同样的错误; ie the same error occurs with this line: 即此行发生相同的错误:
v.emplace_back(ListOfA());
MSVC uses the copy constructor of std::list
because its move constructor is throwing. MSVC使用
std::list
的复制构造函数,因为它的移动构造函数正在抛出。 During reallocation, if the move constructor throws, std::vector
cannot provide strong exception guarantee as required by the standard. 在重新分配期间,如果移动构造函数抛出,则
std::vector
无法提供标准所要求的强异常保证。
In your case, the vector does not have any element before reallocation, so it appears that the copy constructor is not called, but that doesn't mean the copy constructor is not needed. 在您的情况下,向量在重新分配之前没有任何元素,因此看起来没有调用复制构造函数,但这并不意味着不需要复制构造函数。
std::list
in libstdc++ and libc++ has noexcept
move constructor. libstdc ++中的
std::list
和libc ++有noexcept
移动构造函数。 This is permitted but not required by the standard. 这是允许的,但标准不要求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.