在 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
.
为什么这不起作用:
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 ofN
elements of typeconst E
, whereN
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
.