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?
constexprwas introduced? I bet theconstarray would work if it had static storage duration, mind you. Can you present the standard wording that you think should make it valid as it is?staticdidn't make any difference. I have some understanding of whyconstexprwas introduced but there are gaps. This question illustrates some of that gap.[expr.const]and friends. Happy reading!const size_t IntArray[2] = {1, bar()};forconstexpr size_t a = intArray[0 /* or 1 */];, it would be tricky and requires to remember for each index if it is a compile time value or not.constdoes not guarantee the value can be determined at compile time whileconstexprdoes.