modification of ‘<temporary>’ is not a constant expression

Viewed 391

This code used to compile with earlier g++ versions, e.g. 5.3. Using 10.2 I'm getting the following (using compiler option -std=c++11)

tmp1.cpp: In function ΓÇÿint main(int, char**)ΓÇÖ:
tmp1.cpp:17:117: error: modification of ΓÇÿ<temporary>ΓÇÖ is not a constant expression
   17 | static constexpr std::initializer_list<std::pair<int, std::initializer_list<int> > > s={{0, {1}}, {1, {2}}, {2, {3}}};
      |                                                                                                                     ^
tmp1.cpp:18:33: error: non-constant condition for static assertion
   18 | static_assert(isSortedPairVector(s.begin(), s.end()), "sorted");
      |               ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~

I think this has something to do with an initializer_list containing another initializer_list -- as with

std::initializer_list<std::pair<int, int> > 

everything is fine. Here is the code:

#include <initializer_list>
#include <utility>
#include <iostream>


template<typename T>
constexpr bool isSortedPairVector(const T&_p, const T&_pEnd)
{   return _p == _pEnd || _p + 1 == _pEnd
        ? true
        : _p->first < (_p + 1)->first
            && isSortedPairVector(_p + 1, _pEnd);
}


int main(int, char**)
{
static constexpr std::initializer_list<std::pair<int, std::initializer_list<int> > > s={{0, {1}}, {1, {2}}, {2, {3}}};
static_assert(isSortedPairVector(s.begin(), s.end()), "sorted");
}

Curiously -- making the contained initializer_list empty makes the code compileable. e.g.

static constexpr std::initializer_list<std::pair<int, std::initializer_list<int> > > s={{0, {}}, {1, {}}, {2, {}}};
1 Answers

The solution to this problem is to make every std::initializer_list object used inside another std::initializer_list a constexpr variable. Thus the following compiles:

static constexpr std::initializer_list<int> s1({1, 2});
static constexpr std::initializer_list<
    std::pair<int, std::initializer_list<int> > 
> s={
    {0, s1},
    {1, s1},
    {2, s1}
};
Related