32

次の例を参照してください。

struct Foo
{
    int a;
    int b;

    bool operator == (const Foo & x)
    {
        return a == x.a && b == x.b;
    }
};

int main ()
{
    Foo a;

    a = {1, 2};

    if (a == {1, 2}) // error: expected primary-expression before ‘{’ token
    {
    }
}

ラインa={1,2}は大丈夫です。Foo中かっこは、暗黙的なメソッドの引数の型と一致するように a に変換されますoperator=operator=ユーザー定義の場合でも機能します。

示されているように行if (a=={1,2}})エラー。

式がユーザー定義メソッドに一致{1,2}するように変換されないのはなぜですか?Foooperator==

4

5 に答える 5

41

一般的なケースでは、リスト初期化を演算子の引数として使用することはできません。C++11 標準のパラグラフ 8.5.4/1:

[...] リストの初期化を使用できます

— 変数定義の初期化子として (8.5)

— 新しい式の初期化子として (5.3.4)

— return ステートメント (6.6.3)

— for-range-initializer (6.5) として

関数の引数として(5.2.2)

— 下付き文字として (5.2.1)

— コンストラクター呼び出しの引数として (8.5、5.2.3)

— 非静的データメンバーの初期化子として (9.2)

— mem-initializer (12.6.2)

割り当ての右側(5.17)

operator =最後の項目は、リストの初期化が一般に任意の演算子に対して許可されていないにもかかわらず、の右側で許可されている理由を説明しています。

ただし、上記の 5 番目の項目により、通常の関数呼び出しの引数として次のように使用できます。

if (a.operator == ({1, 2}))
于 2013-04-23T12:21:35.560 に答える
7

単にサポートされていないだけです。

初期化子リストは、初期化( [C++11: 8.5.4]) および代入で有効であることが明示的に定義されています。

[C++11: 5.17/9]:ブレース初期化リストが右側に表示される場合があります

  • スカラーへの代入。この場合、イニシャライザ リストは最大で 1 つの要素を持つ必要があります。の意味はx={v}T式 のスカラー型ですxx=T(v)ただし、縮小変換 (8.5.4) は許可されません。の意味はx={}ですx=T()
  • ユーザー定義の代入演算子によって定義された代入。この場合、初期化子リストが引数として演算子関数に渡されます。

他の恣意的なケースを許可する標準的な表現はありません。

許可された場合、この例では、 の型は{1,2}かなりあいまいになります。実装するのは複雑な言語機能になります。

于 2013-04-23T12:22:23.710 に答える
4

明示的なキャストが必要です。

if (a == (Foo){1, 2})
{
}
于 2013-04-23T12:22:49.127 に答える
0

ユーザー定義型 a および == 演算子を含む式を使用している場合オーバーロードされた演算子関数が呼び出され、指定した定義に従って、クラス Foo のオブジェクトの参照の引数が必要です

したがって、式は a==b のようになります

ここで、b はクラス Foo のオブジェクトです

ここで、この式を使用すると、b と a のデータ メンバーを比較して、それらが等しいかどうかを知ることができます。

于 2013-04-23T12:23:25.037 に答える