2017-05-01 10 views
7

は、以下のコードを検討:ポインタに関連する演算子を適用

struct X 
{ 
    int x; 
}; 

X xInstance; 

class A 
{ 
public: 
    operator X*() 
    { 
     return &xInstance; 
    } 
}; 

int main() 
{ 
    A a; 
    *a = X(); // ok 
    a[0] = X(); // ok 
// a->x = 0; // error 
} 

Aポインタ型への暗黙的な変換を有します。私はポインターが必要な3つの状況でそれを使用しようとします。最初の2行は問題ありませんが、に暗黙的に変換されたstruct Xoperator->のフィールドを参照しようとすると機能しません。何故ですか?概念的には、operator[]operator->とどのように異なるのですか? g++ 6.3.0およびVC++ 2017

答えて

6

標準セクション13.6リストオーバーロード解決のために内蔵の演算子を表す「候補オペレータ機能」でテスト

。オペレータ@の少なくとも1つの部分式にクラスまたは列挙型がある場合、オーバーロード解決のために考慮する関数のリストは、非メンバー参照の和である[email protected]、メンバー参照の[email protected]、およびこれらの候補演算関数です。

ほとんどの演算子では、候補演算子関数は、組み込み演算子で許可されているすべての型を表すのに十分です。例えば、すべてのCV修飾またはCVのための形態

T& operator*(T*); 

のすべてのCV修飾TまたはCV-非修飾オブジェクトタイプ、そこに存在する候補オペレータの機能のために

不適格オブジェクトタイプTフォームの候補オペレータ関数が存在します

あなたが*aa[0]を書くときに対応する候補オペレータ機能は、オーバーロードの解決に勝っ
T& operator[](T*, std::ptrdiff_t); 
T& operator[](std::ptrdiff_t, T*); 

、部分式は、候補演算子関数の引数の型に変換した後、通常の組み込みの演算子の規則が適用されますされています。

ただし、このセクションでは、operator->の候補演算子関数はリストしていません。したがって、aにクラスタイプがある場合、a->xの唯一の可能な機能は、メンバー参照でa.operator->()です。 (メンバー以外の参照は、常にメンバ関数でなければならないoperator->には当てはまりません)。

+0

C++ 14 [over.match.oper] /3.3では、特に 'operator->'の場合には 演算子& ')ビルトインの候補セットは空です –

+0

@MM良いキャッチです。私はそれがどこかにあったと思った。 – aschepler