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