繁体   English   中英

std :: move-only类型的列表:无法在VC ++中进入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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM