4

I have a class, called group, that shall keep a number of base classes inside it, held in std::unique_ptrs (polymorphism). The order does not matter, nor does if some of the elements are equal between them. It's a task for a std::vector, that I would ideally flag as const in the member declaration.

As part of the design, I would like to pass all the elements that will fit into the group object in an initializer_list, like this:

class base;

class derived1 : base;
class derived2 : base;
class derived3 : base;

group my_object({ new derived1() , new derived2() , new derived3() });

But I'm having trouble with the following:

  • The vector inside the group class will be made up of std::unique_ptr, not objects.
  • As std::initializer_lists may only hold objects of one type, that type shall be a pointer-to-base-class.

Taking all that into account, how should I implement it? As the elements held in the group class' vector are not supposed to change, it's much more efficient to initialize it in the initialization list of the constructor. However, std::unique_ptrs are not copyable, and I can't figure out how to construct a vector of unique_ptr<base_class> from an initializer_list made up of raw pointers.

djsp
  • 2,174
  • 2
  • 19
  • 40
  • @jrok Sorry, it was a typo. – djsp Jun 16 '13 at 17:02
  • *"it's much more efficient to initialize it in the initialization list of the constructor"* -- Are you sure? Is it really more efficient than calling `reserve()` on the vector, then calling push_back/emplace_back for each pointer? The source code might be more aesthetically pleasing, but I doubt you would notice a difference in efficiency. – Benjamin Lindley Jun 16 '13 at 17:20
  • possible duplicate of [Can I list-initialize a vector of move-only type?](http://stackoverflow.com/questions/8468774/can-i-list-initialize-a-vector-of-move-only-type) – juanchopanza Jun 16 '13 at 17:21

1 Answers1

3

You can make an initialization list like this:

#include<memory>

class base{};

class derived1 : public base{};
class derived2 : public base{};;
class derived3 : public base{};;

using namespace std;
int main (){
  auto ptrs={ unique_ptr<base>(new derived1()) , unique_ptr<base>(new derived2()) , unique_ptr<base>(new derived3()) };

}

But the problem seems to be that you can not move from that initializer list since initializer lists are constant. There is more on this here. initializer_list and move semantics

I asked a related but different question at in-place vector construction from initialization list (for class with constructor arguments)

Community
  • 1
  • 1
Johan Lundberg
  • 26,184
  • 12
  • 71
  • 97
  • But how would I handle that in the constructor of my `group` class? How can I tell the constructor of a `vector` to take the objects inside an `initializer_list` and *move* them? – djsp Jun 16 '13 at 17:08
  • 1
    initializer_lists are constant. they just can not be moved from. – Johan Lundberg Oct 01 '15 at 21:12