繁体   English   中英

非模板函数的尾随要求子句的编译器差异

[英]Compiler variance for trailing requires-clauses on non-templated functions

考虑以下示例:

void f() requires true { }
int main() { f(); }

Clang (1) ( DEMO ) 接受这个程序,而 GCC (1) ( DEMO ) 拒绝它并出现以下错误:

 error: constraints on a non-templated function

请注意,约束表达式实际上可以在 Clang 的情况下使用,因为以下程序被 Clang 拒绝:

void f() requires false { }
int main() { f(); }  //  // error: no matching function for call to 'f'

Clang 注意到声明的f不是候选者,因为不满足约束(因为它是f()调用的候选者; DEMO )。

  • 哪个编译器在这里是正确的,什么是(/是)管理这个的相关标准规则(/s)?

(1) GCC HEAD 11.0.0 20210124 和 Clang HEAD 12.0.0 (20210124),-std -std=c++20

除非另有说明,否则以下所有标准参考均指N4861(2020 年 3 月布拉格后工作草案/C++20 DIS)


这是一个 Clang 错误,并且 GCC 根据[dcl.decl]/4 (以及[temp.constr.decl]/1 )拒绝该程序是正确的[强调我的]:

仅当声明符声明模板化 function ([dcl.fct]) 时, init-declarator成员声明符中的可选requires 子句才应存在 当出现在声明符之后时, requires-clause称为尾随 requires-clause [...]

同一段落还包含一个(非规范性)示例,明确指出 OP 的示例格式错误:

[示例:

 void f1(int a) requires true; // error: non-templated function template<typename T> auto f2(T a) -> bool requires true; // OK //...

结束示例]

我们可能会注意到,在(成为 C++20)工作草案的早期版本中, N4810 ,[dcl.decl]/4 对允许出现 requires 子句的位置的要求较弱:

当声明符未声明 function (9.2.3.5) 时, init-declaratormember-declarator中的可选requires-clause (第 13 条)不应出现。 [...]

[示例:

 void f1(int a) requires true; // OK //...

结束示例]

其中 OP 用例的非规范示例被明确显示为格式正确。 可以说,最初的意图是允许基于 class 模板的模板参数来约束 class 模板的非模板成员函数:

#include <iostream>

template<bool B>
struct S {
    void f() requires   B  { std::cout << "true\n"; }
    void f() requires (!B) { std::cout << "false\n"; }
};

int main() { 
    S<true>{}.f();   // true
    S<false>{}.f();  // false
} 

这在 N4861 中 [dcl.decl]/4 的最终 state(用于 C++20)中仍然允许,其中限制是模板化 function的限制(参见[temp.pre]/8中的模板化实体, particularly [temp.pre]/8.3 ), which does not only cover function templates (and function template members of non-templates and template class templates), but also non-template member functions of class templates.


Clang 错误报告:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM