[英](involving explicit)Precedence with operator and constructor conversion
我瀏覽了很多與轉換相關的問題,但似乎沒有人以這種方式討論顯式關鍵字。 這是代碼:
struct B;
struct A{
/*explicit*/ A(const B&){ cout << 1; } // *1
};
struct B{
/*explicit*/ operator A()const{ cout << 2; } // *2
};
void foo(const A &){}
int main(void){
B b;
foo( /*static_cast<A>*/ (b) ); // *3
}
結果:(Y:未注釋,N:注釋,X:或者)
# | *1 | *2 | *3 |output|
1 | N | N | N |error |
2 | N | N | Y | 1 |
3 | N | Y | N | 1 |
4 | N | Y | Y | 1 |
5 | Y | N | N | 2 |
6 | Y | N | Y | 1 |
7 | Y | Y | N |error |
8 | Y | Y | Y | 1 |
1,7是錯誤,這是正常的。(模糊且沒有自動轉換)
2似乎構造函數具有更高的優先級,但為什么呢?
3,5很容易理解。
4很奇怪,因為它沒有調用顯式的。 為什么?
6可能是由於'顯式'或構造函數具有更高的優先級。 哪一個是原因? 8似乎構造函數具有更高的優先級,但為什么呢?
有人可以提供一些解釋嗎? 謝謝!
一個非常好的問題。
首先, explicit
事情並不意味着“如果需要顯式轉換,這具有優先權”。 這意味着“這個東西只能被明確調用”。 因此,它會創建一些無法調用的情況,而不是強制在其他情況下調用它。
另一件需要考慮的事情是static_cast
是直接初始化 ,而將參數傳遞給函數是復制初始化 。 除其他外,復制初始化從不使用顯式構造函數。 另外需要注意的是,直接初始化需要使用類的構造函數(顯式或非顯式)。 雖然這並不意味着轉換不能執行直接初始化:它可以用於轉換構造函數的參數,如果構造函數是編譯器生成的副本,那么它看起來就像轉換函數執行直接初始化(實際上它是由復制構造函數執行的)。 嘗試聲明復制構造函數而不定義它(禁用復制技術),你會發現轉換函數不再適用於直接初始化上下文:它將編譯,但會導致鏈接錯誤。
考慮到這一點:
explicit
聲明轉換函數只會阻止它被隱式調用,它不會強制在顯式上下文中使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.