AndyMcoy
AndyMcoy

Reputation: 361

Compiler not using move c'tor / assignment oper?

Simple question really. What is going on in the following example code that causes it not to compile?

The error occurs at the first line of 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;
}

I'm compiling it as c++0x code, in which I understand atomic types maybe can't be copied? But either way, the line vector<Test> v = { Test(), Test() }; should invoke the default move constructor/assignment operator of Test, which ought to call the move constructor/assignment operator of Test::dq, avoiding the need to copy any atomic_int.

So why won't this compile?

EDIT

My compiler will allow me to add non-moveable objects to a container, and then move the container. See below:

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


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

    return 0;
}

A move is performed on t1, which invokes a move of t1's members, one of which is a deque. So a move of each member in deque occurs, none of which are of type atomic_int

Upvotes: 1

Views: 153

Answers (1)

T.C.
T.C.

Reputation: 137315

Since C++11, having a container of only default constructible objects is perfectly legal, provided that you do not use any operation that requires the object to be copyable or movable.

However, std::initializer_list allows only const access to its elements, meaning that you can't move from them. Hence

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

would attempt to copy a Test, which is not valid because it would attempt to copy the deque.

Upvotes: 3

Related Questions