编译器不使用 move c'tor / assignment oper?

Compiler not using move c'tor / assignment oper?

真的很简单的问题。以下示例代码中发生了什么导致它无法编译?

错误出现在main()的第一行:

"Use of deleted function 'std::__atomic0::...__atomic_base(...)')"

#include <atomic>
#include <deque>
#include <vector>

using namespace std;

class Test {
public:
    deque<atomic_int> dq;
    Test(){}
};


int main(){
    vector<Test> v = { Test(), Test() };

    return 0;
}

我正在将其编译为 c++0x 代码,其中我理解 atomic 类型可能无法复制?但无论哪种方式,行 vector<Test> v = { Test(), Test() }; 应该调用 Test 的默认 move constructor/assignment 运算符,它应该调用 move constructor/assignment Test::dq 运算符,避免复制任何 atomic_int.

那为什么不能编译呢?

编辑

我的编译器允许我将不可移动的对象添加到容器中,然后移动容器。见下文:

class Test {
public:
    deque<atomic_int> dq;
    Test(){
        dq.resize(10);
    }
};


int main(){
    Test t1;
    Test t2(std::move(t1));

    return 0;
}

t1 执行了一次移动,它调用了 t1 成员的一次移动,其中之一是 deque。因此 deque 中的每个成员都发生了移动,其中 none 的类型为 atomic_int

自 C++11 起,拥有仅包含默认可构造对象的容器是完全合法的,前提是您不使用任何要求对象可复制或可移动的操作。

但是,std::initializer_list 只允许 const 访问其元素,这意味着您不能从它们中移动。因此

vector<Test> v = { Test(), Test() };

会尝试 复制 一个 Test,这是无效的,因为它会尝试复制 deque.