Reputation: 3975
With a std::array
you can initialize it like this:
std::array<int,5> myArray = {1,2,3,4,5};
If I where trying to create my own array class how would I do something similar?
Upvotes: 2
Views: 97
Reputation: 37606
std::array
rely on aggregate initialization (the C way of initializing struct), basically this is valid c++:
struct A {
int values[2];
size_t size;
};
A a = {{42, 44}, 2U}; // No constructor involved
// | |--- a.size
// |--- a.values
Now if you remove the size
attribute, you get:
struct A {
int values[2];
};
A a = {{42, 44}}; // Valid!
But c++ gives you something called brace-elision we allow you to omit the inner brackets, so:
A a = {42, 44}; // Still valid!
Now, just makes A
a template:
template <typename T, size_t N>
struct A {
T data[N];
};
A<int, 2> a = {{42, 44}};
Note that this does not makes use of initializer_list
which are used for std::vector
, std::list
, and so on.
Also note that:
A<int, 2> a1{42, 44}; // Not valid prior to c++14
A<int, 2> a2{{42, 44}}; // Ok even for c++11
And note that clang will throw warning whatever the version you use by default.
A minimalist version of std::array
could look like this:
template <typename T, size_t N>
struct my_array {
T _data[N];
T& operator[] (size_t i) { return _data[i]; }
const T& operator[] (size_t i) const { return _data[i]; }
constexpr size_t size () const { return N; }
T* begin () { return _data; }
const T* begin () const{ return _data; }
T* end () { return _data + size(); }
T* end () const { return _data + size(); }
};
Please note that the standard std::array
has a lot more stuff than this (a lots of typedef
s, other methods
, a lots of overloads, ...), but this is a small base to get you started.
Also note that _data
has to be public
so that aggregate initialization can work (it does not work if you have private
/ protected
members!).
Upvotes: 4
Reputation: 48928
Here is a simple implementation that supports initializing with a list of elements:
//template class 'array' takes 'T' (the type of the array) and 'size'
template<typename T, std::size_t size>
class array
{
public:
//This is the concept of initializer lists (wrapper around variadic arguments, that
//allows for easy access)
array(std::initializer_list<T> list)
{
//Loop through each value in 'list', and assign it to internal array
for (std::size_t i = 0; i < list.size(); ++i)
arr[i] = *(list.begin() + i); //list.begin() returns an iterator to the firsts
//element, which can be moved using +
//(deferenced to get the value)
}
//Overloads operator[] for easy access (no bounds checking!)
T operator[](std::size_t index)
{
return arr[index];
}
private:
T arr[size]; //internal array
};
You can then use it like so:
array<int, 2> a = { 2, 5 };
int b = a[0]; //'b' == '2'
Upvotes: 1