简体   繁体   English

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

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

Consider the following example:考虑以下示例:

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

Clang (1) ( DEMO ) accepts this program, whereas GCC (1) ( DEMO ) rejects it with the following error: Clang (1) ( DEMO ) 接受这个程序,而 GCC (1) ( DEMO ) 拒绝它并出现以下错误:

 error: constraints on a non-templated function

Note that the constraint expression can actually be used in Clang's case, as the following program is rejected by Clang:请注意,约束表达式实际上可以在 Clang 的情况下使用,因为以下程序被 Clang 拒绝:

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

with Clang noting that that the declared f is not a candidate as the constraints were not satisfied (for it to be a candidate for the f() call; DEMO ). Clang 注意到声明的f不是候选者,因为不满足约束(因为它是f()调用的候选者; DEMO )。

  • Which compiler is correct here, and what is(/are) the relevant standard rule(/s) that govern this?哪个编译器在这里是正确的,什么是(/是)管理这个的相关标准规则(/s)?

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

All standard references below refer, unless noted otherwise, to N4861 (March 2020 post-Prague working draft/C++20 DIS) .除非另有说明,否则以下所有标准参考均指N4861(2020 年 3 月布拉格后工作草案/C++20 DIS)


This is a Clang bug, and GCC is correct to reject the program, as per [dcl.decl]/4 (as well as [temp.constr.decl]/1 ) [ emphasis mine]:这是一个 Clang 错误,并且 GCC 根据[dcl.decl]/4 (以及[temp.constr.decl]/1 )拒绝该程序是正确的[强调我的]:

The optional requires-clause in an init-declarator or member-declarator shall be present only if the declarator declares a templated function ([dcl.fct]).仅当声明符声明模板化 function ([dcl.fct]) 时, init-declarator成员声明符中的可选requires 子句才应存在 When present after a declarator, the requires-clause is called the trailing requires-clause .当出现在声明符之后时, requires-clause称为尾随 requires-clause [...] [...]

The same paragraph also contains a (non-normative) example explicitly pointing out the OP's example as ill-formed:同一段落还包含一个(非规范性)示例,明确指出 OP 的示例格式错误:

[ Example: [示例:

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

end example ] 结束示例]

We may note that in an earlier version of the (to become C++20) working draft, N4810 , [dcl.decl]/4 had a weaker requirement for where requires-clauses were allowed to appear:我们可能会注意到,在(成为 C++20)工作草案的早期版本中, N4810 ,[dcl.decl]/4 对允许出现 requires 子句的位置的要求较弱:

The optional requires-clause (Clause 13) in an init-declarator or member-declarator shall not be present when the declarator does not declare a function (9.2.3.5).当声明符未声明 function (9.2.3.5) 时, init-declaratormember-declarator中的可选requires-clause (第 13 条)不应出现。 [...] [...]

[ Example: [示例:

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

end example ] 结束示例]

where the non-normative example of the use case of the OP was explicitly shown as well-formed.其中 OP 用例的非规范示例被明确显示为格式正确。 The original intent there was arguably to allow constraining of non-template member functions of class templates based on the template parameters of the class template:可以说,最初的意图是允许基于 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
} 

this is still allowed in the final state (intended for C++20) of [dcl.decl]/4 in N4861, where the restriction is to that of a templated function (see templated entity in [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.这在 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 bug report: Clang 错误报告:

暂无
暂无

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

相关问题 C ++:调用模板化类的非模板化函数 - C++: call non-templated functions of a templated class 如何专门化非模板类的模板成员函数? - how to specialize templated member functions of non-templated classes? 适当组织模板化和非模板化功能的混合,最终用户无法访问 - Proper organization for a mixture of templated and non-templated functions not accessible to the end-user 在具有相同签名的模板化功能和非模板化功能之间进行选择时,为什么没有歧义? - Why no ambiguity when choosing between templated and non-templated functions with same signatures? “重载”模板化和非模板化类型 - “Overloading” templated and non-templated types 模板成员函数不能从同一类C ++中调用非模板成员函数 - Templated member functions cannot call non-templated member function from same class, C++ C++ 隐式转换规则为什么以及如何区分模板转换函数和非模板转换函数? - Why and how do the C++ implicit conversion rules distinguish templated conversion functions from non-templated? 为什么非模板化函数具有相同的名称和参数但返回类型不同是非法的? (但模板功能合法吗?) - Why is it illegal for non-templated functions to have same name and arguments but different return types? (but legal for template functions?) 非模板类的显式类实例化 - Explicit class instantiation for non-templated classes Template类非模板化方法参数 - Template class non-templated method argument
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM