簡體   English   中英

Static 和非靜態成員 function 模板具有相同的參數類型和 C++ 中的 requires 子句

[英]Static and non-static member function templates with the same parameter types and requires clause in C++

Static 和具有相同參數類型的非靜態成員函數不能重載。 但是,如果成員函數是模板並且其中一個具有requires子句,則所有編譯器都允許它。 但是當調用這兩個成員函數時就會出現問題:

struct A {
    static int f(auto) { return 1; }
    int f(auto) requires true { return 2; }
};

int main() {
    [[maybe_unused]] int (A::*y)(int) = &A::f; // ok everywhere (if no below line)
    [[maybe_unused]] int (*x)(int) = &A::f; //ok in GCC and Clang (if no above line)
}

如果main()中只剩下一行(任意),則 GCC 和 Clang 接受該程序。 但是當main()中的兩行都存在時, Clang 會打印

error: definition with same mangled name '_ZN1A1fIiEEiT_' as another definition

和 GCC 報告內部編譯器錯誤。 演示: https://gcc.godbolt.org/z/4c1z7fWvx

所有編譯器在接受帶有重載 static 和非靜態成員函數的struct A定義時是否都是錯誤的? 或者他們只是在調用這兩個函數時有類似的錯誤。

這很混亂,在瀏覽標准時,我在[over.over]中發現了這個更簡單的示例:

struct X {
  int f(int);
  static int f(long);
};

int (X::*p1)(int)  = &X::f;     // OK
int    (*p2)(int)  = &X::f;     // error: mismatch
int    (*p3)(long) = &X::f;     // OK

所以我首先嘗試了這兩個有效的行,但即使它們也被所有三個編譯器拒絕(彼此獨立)。 這是一個問題。

進一步看,關於 function 模板的地址, [temp.deduct.funcaddr]說:

模板 arguments 可以從取重載集地址時指定的類型推導出來。 如果有目標,則使用 function 模板的 function 類型和目標類型作為 P 和 A 的類型,並按照 [temp.deduct.type] 中的說明進行扣除。 否則,對類型 P 和 A 的空集進行推導。

此類目標在[over.over]中進行了描述,在您的示例中屬於第一種類型:

(1.1) 一個 object 或正在初始化的引用 ([dcl.init], [dcl.init.ref], [dcl.init.list]),

甚至在考慮任何約束之前,在我看來,編譯器應該能夠在兩種情況下識別唯一的候選者,就像在更簡單的示例中一樣,因為目標具有不同的簽名。

根據 最新的 C++20 標准草案 class.static.mfct#2

不應存在同名和同參數類型([over.load])的 static 和非靜態成員 function。

這里沒有例外,因為requires -clause 的存在來區分成員函數,只有相同的名稱和相同的參數類型。 所以struct A的定義在 C++20 中是錯誤的。

同一項目在C++23 的初稿中被改寫,class.static.mfct#2

不能有一個 static 和一個非靜態成員 function 具有相同的名稱、參數類型列表和尾隨要求子句([over.load])。

據此, A的定義已經很好了。 看起來 GCC、Clang 和 MSVC 即使在 C++20 模式下也都遵循此語句。 我們觀察到的錯誤發生是因為兩個函數的名稱相同(保留當前 ABI 幾乎無法修復)。

And in the latest draft of C++, class.static.mfct#2 any restriction on having static and not-static member functions with same name and parameters are removed.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM