Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement an initializer list for user defined type? (analogus to std::vector initializer list)

std::vector can be initialized as

std::vector<std::string> words1 {"the", "frogurt", "is", "also", "cursed"}; 

Reference

Now if want to achieve the similar functionality for one of my types, how do I go about doing it? How should I implement the constructor for this functionality?.

How does the standard support me achieving this (reference to standard will be most helpful)?. Basically, if you could teach me how it's implemented for std::vector it will be sufficient.

Can this also be done prior to C++11?

Also, can I have a POD struct type initializer list so that I can have values with different types to initialise my type?

like image 776
Koushik Shetty Avatar asked May 09 '13 05:05

Koushik Shetty


1 Answers

Create a constructor which takes a std::initializer_list as a parameter:

#include <vector>
#include <initializer_list>

template <typename T>
struct foo
{
private:
    std::vector<T> vec;

public:

    foo(std::initializer_list<T> init) 
      : vec(init)
    { }
};


int main()
{
    foo<int> f {1, 2, 3, 4, 5};
}

std::vector does this is almost exactly the same way (although utilizing begin() and end() - std::initializer_list has iterators much the same way as other containers do). From gcc:

  vector(initializer_list<value_type> __l,
     const allocator_type& __a = allocator_type())
  : _Base(__a)
  {
_M_range_initialize(__l.begin(), __l.end(),
            random_access_iterator_tag());
  }

Edit: I'm not 100% what you're trying to do, but you may simply be able to use uniform initialization to get what you want:

struct bar
{
private:

    int i;
    double j;
    std::string k;

public:

    bar(int i_, double j_, const std::string& k_)
      : i(i_), j(j_), k(k_)
    { }

};

int main()
{
    bar b {1, 2.0, "hi"};
}
like image 151
Yuushi Avatar answered Oct 20 '22 23:10

Yuushi