“<temporary>”的修改不是一个常量表达式。

3

这段代码以前可以使用较早的g++版本编译,例如5.3版本。但当我使用10.2版本并加入编译器选项-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");
      |               ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~

我认为这与包含另一个initializer_list的initializer_list有关--就像

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

一切都好。以下是代码:

#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");
}

有趣的是,将包含的initializer_list设为空会使代码可编译,例如:

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

这似乎只是一个漏洞。你尝试过报告它吗? - Brian Bi
暂时还没有——与此同时,我相信编译器对于C++的了解比我更深。 - user12411795
有趣。我的g++(8.3.0)编译没有问题,但我的clang++(7.0.1)出现错误:“error: constexpr variable 's' must be initialized by a constant expression”,“note: pointer to subobject of temporary is not a constant expression”,“note: temporary created here”,指向{1} - max66
2
std::initializer_list 不是一个具有所有权的容器,它主要是对临时 C 数组的视图。 - Jarod42
1个回答

1
这个问题的解决方案是将每个在另一个std::initializer_list中使用的std::initializer_list对象变成一个constexpr变量。 因此以下代码可以编译通过:
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}
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接