The problem this change solves is the ability to use a non-const std::array within a constexpr function to compute some result. Recall that constexpr functions can't call non-constexpr functions when being evaluated at compile-time.
As an example consider a function that computes the sum of i = 1 to N. And for argument's sake consider a really stupid way of doing it (non-stupid examples exist in the real world, but are more complicated than this): Create an array initialized with {1, 2, 3, ...} and then returning the sum of the elements of the array.
// Compute sum from i = 1 to N
template <unsigned N>
unsigned
sum() noexcept
{
std::array<unsigned, N> a{};
unsigned u = 1;
for (auto i = a.begin(); i != a.end(); ++i, ++u)
*i = u;
u = 0;
for (auto const x : a)
u += x;
return u;
}
This works fine and can be called like this:
auto x = sum<5>(); // x == 15
Now somebody says: Hey, let's compute this at compile time!
In C++17 this is as simple as slapping constexpr onto sum and x:
// Compute sum from i = 1 to N
template <unsigned N>
constexpr
unsigned
sum() noexcept
...
constexpr auto x = sum<5>(); // x == 15
But in C++14 this doesn't compile:
test.cpp:24:20: error: constexpr variable 'x' must be initialized by a constant expression
constexpr auto x = sum<5>();
^ ~~~~~~~~
test.cpp:11:21: note: non-constexpr function 'begin' cannot be used in a constant expression
for (auto i = a.begin(); i != a.end(); ++i, ++u)
^
And the reason it doesn't compile is because array<T, N>::begin() is not a constexpr function.