在 C++14 中将 constexpr intializer_list 作为参数传递

pass constexpr intializer_list as argument in c++14

为什么这不起作用:

constexpr initializer_list<int> ilist = {1,2,3,4};
constexpr int my_min = min(ilist);

同时这样做:

constexpr int my_min = min({1,2,3,4});

我的代码基于 constexpr std::min() 函数,如图 here 并且我使用 clang3.5.0 编译器(g++4.9.1 似乎没有要注意 constexpr std::min()).

我无法理解我遇到的错误:

clang35 -stdlib=libc++ -std=c++14 test.cpp  -o test;
test.cpp:158:35: error: constexpr variable 'ilist' must be initialized by a constant expression
  constexpr initializer_list<int> ilist = {1,2,3,4};
                                  ^       ~~~~~~~~~
test.cpp:158:35: note: pointer to subobject of temporary is not a constant expression
test.cpp:158:43: note: temporary created here
  constexpr initializer_list<int> ilist = {1,2,3,4};
                                          ^
test.cpp:159:17: error: constexpr variable 'my_min' must be initialized by a constant expression
  constexpr int my_min = min(ilist);
                ^        ~~~~~~~~~~
test.cpp:159:30: note: initializer of 'ilist' is not a constant expression
  constexpr int my_min = min(ilist);
                             ^
test.cpp:159:30: note: in call to 'initializer_list(ilist)'
test.cpp:158:35: note: declared here
  constexpr initializer_list<int> ilist = {1,2,3,4};

C++14 尚未在 g++ 和 clang++ 中完全实现。在您的特定情况下:g++ STL 没有实现 template constexpr T min(std::initializer_list ilist); 而 clang++ 还没有 initializer_list 的 constexptr 构造函数。

与第二个片段不同,第一个片段无法编译的原因是创建基础数组的时间点。 [dcl.init.list]/5:

An object of type std::initializer_list<E> is constructed from an initializer list as if the implementation allocated a temporary array of N elements of type const E, where N is the number of elements in the initializer list.

现在,当调用 min 时,我们访问该数组的元素。但是,[expr.const]/7是不可侵犯的:

None 的例外情况适用,但请注意适用于您的第二个示例的最后一个要点。

Clang 是(不出所料)正确的,而 GCC 错误地接受了您的代码。上述裁决也是@dyp 的代码失败的原因:Performing an l-t-r conversion on i is not a constant expression。特别是,(2.7.1) 不适用,因为临时文件不是 const.