Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructor from initializer_list

I am implementing a container in c++, a wrapper for an array in fact. I am not sure how to implement a constructor from initializer_list. I end up with this implementation but it seems to me really ugly. So could be an array allocated in a heap initialized by an initializer_list. Or is there an elegant way how to do it?

template <typename T> class sequence {
public:
    sequence (size_t n): _data {new T[n]}, _size {n} {};
    sequence (std::initializer_list<T> source);
    ~sequence() { delete[] _data; };
private:
    pointer     _data;
    size_type   _size;
};

//Initializer list constructor
template <class T> sequence<T>::sequence (std::initializer_list<T> source)
: sequence(source.size()) {
    auto iterator = source.begin();
    for ( int i=0; i < _size; i++) {
        _data[i] = *iterator;
        ++iterator;
    }
};
like image 512
Jiří Lechner Avatar asked Jun 07 '16 14:06

Jiří Lechner


People also ask

What is initializer_list?

An object of type std::initializer_list<T> is a lightweight proxy object that provides access to an array of objects of type const T .

What is constructor initializer list in C++?

Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.

How do you initialize a data member in C++?

Static Data Member Initialization in C++ For the static variables, we have to initialize them after defining the class. To initialize we have to use the class name then scope resolution operator, then the variable name. Now we can assign some value.

What is uniform initialization in C++?

Uniform initialization is a feature in C++ 11 that allows the usage of a consistent syntax to initialize variables and objects ranging from primitive type to aggregates. In other words, it introduces brace-initialization that uses braces ({}) to enclose initializer values.


1 Answers

Depends on what you're trying to do.

If you're actually needing to use a sequence with bounded size, as determined at compile-time, then use std::array<T,std::size_t>, which is a wrapper around a C-style array (like what you are implementing), introduced in C++11.

However, as you said in one of your comments, you're doing this mostly for educational purposes. In that case, what you have is decent. The syntax could be cleaned up a little. Consider:

//Initializer list constructor
template <class T> 
sequence<T>::sequence (std::initializer_list<T> source)
  : sequence(source.size()) 
{
  auto it = source.begin();
  auto const e = source.cend();
  auto d = data_;
  while (it != e) {
     *d++ = *it++;
  } 
};

That way you don't explicitly rely on the size(). You could consider making things more efficient by turning the it and e iterators into "move" iterators:

auto it = std::make_move_iterator(source.begin());
auto e = std::make_move_iterator(source.end());

That way, whenever it's dereferenced, its value is cast to an rvalue reference, allowing a move assignment.

like image 186
KyleKnoepfel Avatar answered Sep 30 '22 08:09

KyleKnoepfel