I\'m working on a custom array class in C++ (as a self-led exercise), and I\'m not sure how to create a constructor that allows me to do something along the lines of:
<#include <initializer_list>
// ...
template <typename T>
class array
{
// ...
array(std::initializer_list<T> il);
// ...
template <typename T>
array<T>::array(std::initializer_list<T> il)
{
unsigned long size = il.size();
head = new T[size];
iterator pointer = begin();
for (const T& i : il)
*pointer++ = i;
}
// ...
array<int> test = {1, 2, 3, 4};
DEMO
Suggested improvements:
array(const T rhs[]);
is an equivalent of array(const T* rhs);
, that is, a pointer, which means that sizeof(rhs) / sizeof(T)
expression will not give you the number of items. If you want a special constructor for const char*
, then consider either an entire array<char>
specialization or at least disabling this constructor from the overload resolution if T
is not char
head = new T[size];
default-initializes all elements (calls default constructor for each instance of type T
). Then you call an assignment operation: *pointer++ = *i;
. This can be improved by utilizing a placement-new, like ::new ((void*)ptr) T(*i);
where ptr
is a pointer to a raw, uninitialized memory buffer, like new char[sizeof(T)*size]
or returned from get_temporary_buffer.
And if you are wondering why the following works array<char> test = { "abcd" };
with your current implementation then here is an explanation:
array<T>
class has a constructor taking const T[]
, which for T=char
is instantiated as array<char>::array(const char*)
.
List-initialization can be used to call object's constructor.
Your const T[]
constructor is not explicit, which means that you can use copy-initialization syntax like below:
array<char> test = { "test" };
The expression sizeof(rhs) / sizeof(T)
, although not valid as explained above, for T=char
evaluates to sizeof(char*) / sizeof(char)
, which is (most-probably) 4 / 1 = 4
.
Your "test"
used for initialization has exactly 4 letters, your luck.