簡體   English   中英

(涉及顯式)優先級與運算符和構造函數轉換

[英](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直接初始化 ,而將參數傳遞給函數是復制初始化 除其他外,復制初始化從不使用顯式構造函數。 另外需要注意的是,直接初始化需要使用類的構造函數(顯式或非顯式)。 雖然這並不意味着轉換不能執行直接初始化:它可以用於轉換構造函數的參數,如果構造函數是編譯器生成的副本,那么它看起來就像轉換函數執行直接初始化(實際上它是由復制構造函數執行的)。 嘗試聲明復制構造函數而不定義它(禁用復制技術),你會發現轉換函數不再適用於直接初始化上下文:它將編譯,但會導致鏈接錯誤。

考慮到這一點:

  1. 明顯。
  2. 直接初始化需要構造函數,因此它被調用。
  3. 明顯。
  4. 和2一樣,真的。 explicit聲明轉換函數只會阻止它被隱式調用,它不會強制在顯式上下文中使用它。
  5. 明顯。
  6. 同樣,直接初始化需要構造函數,並允許使用顯式的。
  7. 明顯。
  8. 另一種直接初始化案例

暫無
暫無

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

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