c++constructorstdvectorstdinitializerlist

Initializing a std::vector replacement with single curly braces instead of double curly braces


I have a code similar to the following one:

namespace mine
{
  template<class T>
  using _vector = std::vector<T, my_allocator<T>>;

  template<class T>
  class myvector : public _vector<T>{};
};

This works in most cases as my own std::vector drop-in replacement, but it doesn't quite work at initializing it with a list like with a normal std::vector:

#include "myvector.h"

void foo(void)
{
  std::vector<int> vi = { 1, 2, 3 };
  mine::myvector<int> mvi = { { 1, 2, 3 } };
}

Notice that I have used double curly braces to compile it. So, what I'm missing here? And, more importantly, what can I do to be able to initialize mine::myvector as I do with a normal std::vector?


Solution

  • Note that your class do not have any constructors defined or inherited. So for moment I was wondering how your code compiles at all.

    Your code uses aggregate initialization. Since you do not have any fields just public inheritance, first argument of aggregate initialization is passed to ancestor. This is reason why you need double braces.

    One way to fix it is to inherit constructors from base class. So your class looks like this:

      template<class T>
      class myvector : public _vector<T>{
          using _vector<T>::_vector;
      };
    

    https://godbolt.org/z/qH6s_x

    IMO much better solution would be do not define a class but define alias for type:

      template<class T>
      using myvector = _vector<T>;
    

    https://godbolt.org/z/Pt6sRQ