带有未使用的引用参数的constexpr函数– gcc vs clang [英] constexpr function with unused reference argument – gcc vs clang

查看:97
本文介绍了带有未使用的引用参数的constexpr函数– 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);
    |            ~^~~

godbolt.org上的实时示例

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 of e, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆