C 中的一個類可以定義一個或幾個轉換運算子。其中一些運算子可以對結果型別進行自動扣減。operator auto。所有的編譯器都允許程式員將任何運算子標記為洗掉,運算子auto也是如此。 對于具體型別來說,洗掉意味著試圖呼叫這種轉換將導致編譯錯誤。但是operator auto() = delete的目的是什么?
請看一個例子:
struct A {
operator auto()= delete。
};
struct B : A {
};
int main() {
B b;
A a = b; //span>Clang的錯誤
int i = b; //在Clang和GCC中的錯誤。
int j = a; //在Clang和GCC以及MSVC中的錯誤。
}
由于編譯器無法推匯出結果型別,它實際上禁止從這個類或派生類中進行任何轉換,并出現了錯誤:
function 'operator auto' with deduced return type cannot be used before it is defined.
演示。https://gcc.godbolt.org/z/zz77M5zsx
附帶說明一下,編譯器在仍允許哪些轉換方面略有分歧(例如,GCC和MSVC允許轉換為基類),這里哪一個是正確的?
uj5u.com熱心網友回復:
但是
operator auto() = delete的目的會是什么呢?
下面這個函式的目的是什么呢?
auto f()= delete。
根據語法函式,[dcl.fct.def.general]/1,函式定義的函式體可以是 C 14為函式引入了 這個角落案例是否有用并不是語言真正要考慮的問題,因為引入角落案例總是要付出代價的(例如 "函式定義的語法應該有一個用于 其中哪一個是正確的呢? Clang為這個初始化選擇用戶定義的轉換函式是可以爭論的錯誤。根據[dcl.init.general]/15.6,15.6.2: 否則,如果初始化是直接初始化,或者如果是復制初始化,其中源型別的cv-unqualified版本與目的地的類相同,或者是其派生類,建構式將被考慮。
優先于15.6.3: 除此之外(即,對于其余的復制初始化情況),可以從源型別轉換到目標型別或(當使用轉換函式時)轉換到其派生類的用戶定義的轉換被列舉出來,正如[over.match.copy]中所描述的,并且通過多載決議([over.match])選擇最佳轉換。[...]=洗掉;例如,將一個函式定義為洗掉在語法上是有效的。
auto回傳型別推理,并且給定了函式定義的允許語法,按照C 14,該語法允許明確地洗掉一個具有auto回傳型別的函式。auto型別演繹的特殊案例")。雖然對可以提供顯式預設的函式定義的地方有限制([dcl.fct.def.default]),但同樣的限制并不適用于顯式洗掉的函式定義([dcl.fct.delete])。
A a = b; //錯誤在Clang。
作為語言的使用者,提供一個具有auto回傳型別的函式的洗掉定義可以用于語意上的標記,即任何人都不應該提供給定函式名稱的任何型別的多載。
auto f()= delete; //從未為f()暴露過有效的多載。
//其他地方::
int f() { return 42; }
//錯誤:只在中不同的函式
//他們的回傳型別不能被多載。
對于用戶定義的轉換運算子的特殊情況,一個明確默認的auto回傳型別的用戶定義的轉換函式可以被使用,例如在一個用于組合的基類中,類似于Scott Meyers C 03的技巧,使一個類不可復制(在C 11引入= delete之前)。
struct NoUserDefinedConversionFunctionsAllowed {
operator auto()= delete;
};
struct S : NoUserDefinedConversionFunctionsAllowed {
operator int() { return1; } //永遠不能使用。
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/306753.html
標籤:
上一篇:基類中的靜態方法反映派生類的名稱
下一篇:多個靜態庫
