1

I understand that the following code does not compile since the move constructor of A is deleted because the mutex is not movable.

class A {
  public:
    A(int i) {}

  private:
    std::mutex m;

};


int main() {    
    std::vector<A> v;
    v.emplace_back(2);
}

But if I want my A to be stored in an std container how should I go about this? I am fine with A being constructed "inside" the container.

user695652
  • 4,105
  • 7
  • 40
  • 58
  • An object that is not copyable or movable simply can't be in a `std::vector`. Think about it: if the vector gets resized and has to reallocate, its elements must be either copied or moved. A container that works is `std::list`. – zindorsky Oct 14 '16 at 18:42
  • http://stackoverflow.com/a/29988626/560648 may be of some interest – Lightness Races in Orbit Oct 14 '16 at 18:47
  • I am confused why I can use the index operator in an std::map without problem: class A { public: void foo() {}; private: std::mutex m; }; int main() { std::map m; m[0].foo(); } – user695652 Oct 14 '16 at 18:47
  • @user695652: Well, that's a completely different example, and a completely different question. This code doesn't require `A` to be copyable or moveable. Only default-constructible. – Lightness Races in Orbit Oct 14 '16 at 18:49
  • @ Lightness Races in Orbit Thanks, could you explain why A does not need to be copy-able/ movable here? Because the std::map is not stored contiguously? emplace would still not work though. – user695652 Oct 14 '16 at 18:52
  • You could also use a `std::vector>` - although that might be a bit less convenient since you'd have to change the `emplace_back` to `v.push_back(std::make_unique(2));` – Daniel Schepler Oct 14 '16 at 19:12

1 Answers1

3

std::vector::emplace_back may need to grow a vector's capacity. Since all elements of a vector are contiguous, this means moving all existing elements to the new allocated storage. So the code implementing emplace_back needs to call the move constructor in general (even though for your case with an empty vector it would call it zero times).

You wouldn't get this error if you used, say, std::list<A>.

aschepler
  • 70,891
  • 9
  • 107
  • 161