[英]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 )。
(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-declarator或member-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.