I was trying to write an compile-time valarray that could be used like this:
constexpr array<double> a = { 1.0, 2.1, 3.2, 4.3, 5.4, 6.5 };
static_assert(a[0] == 1.0, "");
static_assert(a[3] == 4.3, "");
static_assert(a.size() == 6, "");
I managed to do it with the following implementation and it works fine (with GCC 4.7):
#include <initializer_list>
template<typename T>
struct array
{
    private:
        const std::size_t _size;
        const T* _data;
    public:
        constexpr array(std::initializer_list<T> values):
            _size(values.size()),
            _data(values.begin())
        {}
        constexpr auto operator[](std::size_t n)
            -> T
        {
            return _data[n]
        }
        constexpr auto size() const
            -> std::size_t;
        {
            return _size;
        }
};
Even though it works fine for me, I am not sure about the behaviour of std::initializer_list and may use some that are undefined behaviour.
constexpr for std::initializer_list constructor, begin and size is fine even though it is not strictly speaking C++11 since N3471 recently got adopted and made it to the standard.
Concerning the undefined behaviour, I am not sure whether the underlying array of the std::initializer_list will live or if not, whether there is a mean to have it live longer than only array's constructor. What do you think?
EDIT: I may not have been clear, but I do not really care about the actual array. What really interests me is the behaviour of std::initializer_list and its underlying array at compile-time.
Your current code should not compile according to current C++11 rules. When compiled with clang 3.2 I get the following error:
source.cpp:33:28: error: constexpr variable 'a' must be initialized by a constant
expression 
constexpr array<double> a = { 1.0, 2.1, 3.2, 4.3, 5.4, 6.5 };
                        ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is because std::initializer_lists ctors and member functions begin and end are not labeled constexpr. However, there already is a proposal to change this. BTW, libstdc++ already marks these as constexpr.
Now the next problem is the lifetime of the underlying array of std::initializer_list. This is explained in 8.5.4p6:
The array has the same lifetime as any other temporary object (12.2), except that initializing an initializer_list object from the array extends the lifetime of the array exactly like binding a reference to a temporary.
This means that the underlying array has the same lifetime as values object, and expires at the end of your array constructor when it exits. Therefore, _data is pointing to expired memory and _data[n] is undefined behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With