0

I'd like to store an object that contains a unique_ptr in a static container:

Class A
{
public:
    A() {}
    ~A() {}
private:
    unique_ptr<int> p;
};

static vector<A> vec = { A() };

But the code fails to compile, as class A is not copyable due to the unique ptr. How can I solve this, without having to define a copy constructor in class A that would perform a move operation on the pointer?

omer
  • 1,242
  • 4
  • 18
  • 45
  • For example by defining a move constructor for `A` which performs the move. `std::vector` can also live with movable-only types. – Jodocus Nov 21 '17 at 12:29
  • @Jodocus: I tried, and got the same compilation error. Seems like for static containers, the compiler doesn't convert the copy operation to a move operation implicitly. – omer Nov 21 '17 at 12:31
  • You could implement a copy constructor, or a move constructor to your class and this could work, Consider something like `static vector vec = { std::move(A()) };` – immortal Nov 21 '17 at 12:34
  • @immortal `A()` is already an rvalue, doing `std::move` on it does not help – M.M Nov 21 '17 at 12:44
  • 1
    @M.M It won't compile. Initializer lists won't allow the moving of its contents – Passer By Nov 21 '17 at 12:45

3 Answers3

2

First of all, by defining the destructor, you will lose the automatically generated move-constructor. So you either have to remove it or define a proper move constructor. Then, you can initialize it as easy as

static vector<A> vec(1);
Jodocus
  • 7,493
  • 1
  • 29
  • 45
2

Unfortunately, it won't compile as written. When list-initializing (with a {...}) a std::vector, the constructor called is the one with std::initializer_list, and it doesn't allow move semantics.

There are workarounds, but its kind of ugly

static auto vec = []{
    std::vector<A> vec;
    vec.emplace_back();
    return vec;
}();

Live

Passer By
  • 19,325
  • 6
  • 49
  • 96
0

If you want to prevent objects of type A from being copyable, then the only way I see is to use a vector of shared_ptr<A>. Not sure if this meets your requirements or your intent, but at least it works:

static vector<shared_ptr<A>> vec = { make_shared<A>() };
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58