带有未使用的引用参数的constexpr函数– gcc vs clang [英] constexpr function with unused reference argument – gcc vs clang
问题描述
考虑以下代码:
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)失败,出现以下错误:
clang++
(trunk) compiles it. g++
(trunk) fails with the following error:
<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);
| ~^~~
将k(T&)
更改为k(T)
可解决此问题.在我看来,该问题与引用自变量不是常量表达式,但未将其用作k
的一部分有关.
Changing k(T&)
to k(T)
solves the issue. It seems to me that the problem is related to the fact that the reference argument is not a constant expression, but it not used as part of k
.
什么编译器在这里正确?
推荐答案
此处的GCC正确.
根据 [expr.const]/4 :>
表达式
e
是核心常量表达式,除非求值e
的值,按照抽象机的规则,将评估 以下表达式之一:
An expression
e
is a core constant expression unless the evaluation ofe
, following the rules of the abstract machine, would evaluate one of the following expressions:
- ...
- 在 lambda-expression 中,是对变量的引用,该变量具有在 lambda-expression 之外定义的自动存储持续时间, 凡提述为单数用途; ...
- ...
- ...
- in a lambda-expression, a reference to [...] a variable with automatic storage duration defined outside that lambda-expression, where the reference would be an odr-use; ...
- ...
k(i)
odr使用i
,因此k(i)
在lambda表达式中不是常量表达式,因此该代码格式错误.
k(i)
odr-uses i
thus k(i)
is not a constant expression in the lambda expression, so this code is ill-formed.
这篇关于带有未使用的引用参数的constexpr函数– gcc vs clang的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!