簡體   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