2017-09-06 3 views
20

このコード:なぜ{}が最初にstd :: nullptr_tに変換されるのですか?

#include <iostream> 
#include <vector> 

using namespace std; 

void dump(const std::string& s) { 
    cout << s << endl; 
} 

class T { 
public: 
    T() { 
     dump("default ctor"); 
    } 

    T(std::nullptr_t) { 
     dump("ctor from nullptr_t"); 
    } 

    T(const T&) { 
     dump("copy ctor"); 
    } 

    T& operator=(const T&) { 
     dump("copy operator="); 
     return *this; 
    } 

    T& operator=(std::nullptr_t) { 
     dump("operator=(std::nullptr_t)"); 
     return *this; 
    } 

    T& operator=(const std::vector<int>&) { 
     dump("operator=(vector)"); 
     return *this; 
    } 
}; 

int main() { 
    T t0; 

    t0 = {}; 

    return 0; 
} 

outputs

default ctor 
operator=(std::nullptr_t) 

std::nullptr_toperator=を選択した理由は? {}user-defined conversion sequenceにつながる、両方の#1と#2のために

  1. operator=(T const&)
  2. operator=(std::vector<int> const&)
  3. operator=(std::nullptr_t)

+5

'{}'と 'std :: nullptr_t'は標準変換(実際には[over.ics.list]というアイデンティティ変換)ですが、他の変換はユーザ定義ですユーザー定義型。 –

+1

通常、タイプ 'T'が表示されるときはテンプレートパラメータです。これは1秒間私を混乱させた。 –

答えて

18

は、我々は3つの候補を持っています。

ただし、#3の場合{}standard conversion sequenceです。nullptr_tはクラスタイプではないためです。

標準変換シーケンスはbetter thanであり、ユーザ定義の変換シーケンスであるので、#3が勝ちます。

+1

'std :: nullptr_t'がこれをしないようにしたいのであれば、' std :: nullptr_t'から暗黙的に変換可能な独自の型を書くことができます。あいまいなオーバーロードになるでしょう – Justin

+0

'{}'がどのような型を作りましたか? –

+0

@ MarkRansom何が起こったのかは、あなたが求めているのであれば、 'std :: nullptr_t'をバリュー初期化していますか? – Barry

関連する問題