For example if we have an std::array
and we instantiate an element that is out of bound using constexpr
the compiler wouldn't report error:
constexpr int EvaluateSpecialArrayIndex(int a)
{ return a * sizeof(int); }
array<int, 5> arr;
cout << arr[98] << endl; //compiles fine
cout << arr[EvaluateSpecialArrayIndex(4)] << endl; //the same as above
Can't we restrict this somehow?
To ensure that constexpr
functions are evaluated at compile time, you must force them to be by making their result constexpr
. For example:
#include <array>
int
main()
{
constexpr std::array<int, 5> arr{1, 2, 3, 4, 5};
int i = arr[6]; // run time error
}
However:
#include <array>
int
main()
{
constexpr std::array<int, 5> arr{1, 2, 3, 4, 5};
constexpr int i = arr[6]; // compile time error
}
Unfortunately, for this to actually work, std::array
must conform to the C++14 specification, not the C++11 specification. As the C++11 specification does not mark the const
overload of std::array::operator[]
with constexpr
.
So in C++11 you're out of luck. In C++14, you can make it work, but only if both the array
and the result of calling the index operator are declared constexpr
.
Clarification
The C++11 specification for array indexing reads:
reference operator[](size_type n);
const_reference operator[](size_type n) const;
And the C++14 specification for array indexing reads:
reference operator[](size_type n);
constexpr const_reference operator[](size_type n) const;
I.e. constexpr
was added to the const
overload for C++14.
Update
And the C++17 specification for array indexing reads:
constexpr reference operator[](size_type n);
constexpr const_reference operator[](size_type n) const;
The cycle is now complete. The universe can be computed at compile-time. ;-)
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