mardi 28 juillet 2015

Why isn't the operator[] of a std::array temporary constexpr?

I was stuffing some values into a constexpr std::array and then continuing the compile-time static goodness into more constexpr values when I discovered that you can't use an element as a constexpr initializer in C++11.

This is because std::array::operator[] is actually not marked constexpr until C++14: http://ift.tt/1I0cNbx

After a compiler flag upgrade, I can now use an element of a constexpr std::array as a constexpr value:

#include <array>

constexpr std::array<int, 1> array{{3}};
// Initialize a constexpr from an array member through its const operator[]
// that (maybe?) returns a const int & and is constexpr
constexpr int a = array[0];  // Works in >=C++14 but not in C++11

But sometimes I want to use a temporary array in a constexpr computation, and that doesn't work.

// Initialize a constexpr from a temporary
constexpr int b = std::array<int, 1>{{3}}[0];  // Doesn't work!

I get this from clang++ 3.6 with -std=c++14:

prog.cc:9:15: error: constexpr variable 'b' must be initialized by a constant expression
constexpr int b = std::array<int, 1>{{3}}[0];  // Doesn't work!
              ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:9:19: note: non-constexpr function 'operator[]' cannot be used in a constant expression
constexpr int b = std::array<int, 1>{{3}}[0];  // Doesn't work!
                  ^
/usr/local/libcxx-3.5/include/c++/v1/array:183:41: note: declared here
    _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n)             {return __elems_[__n];}
                                        ^
1 error generated.

What's the difference between the two variables I'm indexing into? Why can't I use a direct-initialized temporary std::array's operator[] as constexpr?

Aucun commentaire:

Enregistrer un commentaire