考虑以下代码:
template <int N, typename T> void f(T) { }
template <typename T>
constexpr int k(T&) { return 0; }
int main()
{
constexpr auto i = 1;
f<k(i)>([&i]
{
f<k(i)>(0);
});
}
clang++
(trunk)编译它。g++
(trunk)失败并出现以下错误:
<source>: In lambda function:
<source>:11:19: error: no matching function for call to 'f<k<const int>((* & i))>(int)'
11 | f<k(i)>(0);
| ^
<source>:1:35: note: candidate: 'template<int N, class T> void f(T)'
1 | template <int N, typename T> void f(T) { }
| ^
<source>:1:35: note: template argument deduction/substitution failed:
<source>:11:19: error: '__closure' is not a constant expression
11 | f<k(i)>(0);
| ^
<source>:11:13: note: in template argument for type 'int'
11 | f<k(i)>(0);
| ~^~~
godbolt.org 上的实例
改变k(T&)
to k(T)
解决了这个问题。在我看来,问题与参考参数不是一个事实有关常量表达式,但它不用作k
.
这里哪个编译器是正确的?
GCC 在这里是正确的。
根据[表达式常量]/4:
一种表达e
是核心常量表达式,除非求值
的e
,遵循抽象机的规则,将评估
以下表达式之一:
- ...
- in a lambda 表达式,对[...]一个变量的引用,该变量具有在该变量之外定义的自动存储持续时间lambda 表达式,
其中参考是网上解决使用; ...
- ...
k(i)
网上争议解决用途i
thus k(i)
不是 lambda 表达式中的常量表达式,因此此代码格式错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)