vendredi 29 mai 2015

Using an element of a constexpr array vs a const array to instantiate a template

While answering a question, I ran into an issue that I couldn't explain.

It seems there is large enough difference between

constexpr size_t IntArray[2] = {1, 2};

and

const size_t IntArray[2] = {1, 2};

that the elements of the first can be used to instantiate a template but not the elements of the second.

Sample program that demonstrates the difference.

#include <cstddef>

template <size_t N> struct Foo {};

// Works fine
void test1()
{
   constexpr size_t IntArray[2] = {1, 2};
   const size_t i = IntArray[0];
   Foo<i> f;
   (void)f; // Remove unused f warning.
}

// Does not work
void test2()
{
   const size_t IntArray[2] = {1, 2};
   const size_t i = IntArray[0];
   Foo<i> f;
   (void)f; // Remove unused f warning.
}

int main()
{
   return 0;
}

I get the following compiler error using g++ 4.9.2.

g++ -std=c++11 -Wall    socc.cc   -o socc

socc.cc: In function ‘void test2()’:
socc.cc:17:8: error: the value of ‘i’ is not usable in a constant expression
    Foo<i> f;
        ^
socc.cc:16:17: note: ‘i’ was not initialized with a constant expression
    const size_t i = IntArray[0];
                 ^
socc.cc:17:9: error: the value of ‘i’ is not usable in a constant expression
    Foo<i> f;
         ^
socc.cc:16:17: note: ‘i’ was not initialized with a constant expression
    const size_t i = IntArray[0];
                 ^
socc.cc:17:9: note: in template argument for type ‘long unsigned int’
    Foo<i> f;
         ^
socc.cc:17:12: error: invalid type in declaration before ‘;’ token
    Foo<i> f;

My question is why does the constexpr array work but not the const array?

Aucun commentaire:

Enregistrer un commentaire