3

いくつかのコードサンプルを見てみましょう:

! 4 > 0;

C++ 標準から、比較よりも否定が最初に行われることがわかっています。しかし、この例を少し拡張すると、次のようになります。

#include <iostream>

class Test
{
public:
    bool operator!() const
    {
            std::cout << "operator!" << std::endl;
            return false;
    }

    bool operator>(const int &) const
    {
            std::cout << "operator>" << std::endl;
            return false;
    }
};


int main(int argc, char * argv[])
{
    Test t;
    std::cout << "t > 0;" << std::endl;
    t > 0;
    std::cout << "! t > 0;" << std::endl;
    ! t > 0;
    std::cout << "!t.operator>(0)" << std::endl;
    ! t.operator>(0);

    return 0;
}

このプログラムの出力は次のようになります。

t > 0;
operator>
! t > 0;
operator!
!t.operator>(0)
operator>
  1. 最初の呼び出し (制御呼び出し) は非常に明確です。必要なオペレーターが呼び出されているかどうかを確認します。
  2. 2 回目の呼び出しは、私が最初に述べたことの証明です。否定演算子が最初に呼び出され、結果 (bool) operator> が呼び出されます。
  3. 3回目の電話は私を悩ませているものです。

そして、ここで私の質問が飛び出します。SomeObjInstance > 0call が と異なる理由SomeObjInstance.operator>(0)。2 番目の方法で (メンバーとして) オペレーターを呼び出すことは一般的ではないことはわかっていますが、なぜこの呼び出しが異なるのでしょうか? メンバー演算子が存在しない場合、内部でSomeObjInstance > 0メンバー呼び出しSomeObjInstance.operator>(0)または関数呼び出しに変換されると常に考えていました。bool operator>(const Test &, int)

この動作はC++標準で説明されている場所ですか、それとも未定義の動作ですか?

4

3 に答える 3

6

メンバー アクセス演算子.*は、否定演算子よりも優先され!ます。

この動作はC++標準で説明されている場所ですか、それとも未定義の動作ですか?

これはおそらく関連する段落です。

13.5 オーバーロードされた演算子 [over.oper]

5) 通常、演算子関数は直接呼び出されません。代わりに、実装する演算子を評価するために呼び出されます (13.5.1 – 13.5.7)。ただし、関数呼び出し構文 (5.2.2) で関数の名前として operator-function-id を使用して、明示的に呼び出すことができます。

最初の例t > 0;では、関係比較演算子の優先順位で一致する演算子を使用します。ただし、2 番目のバージョンt.operator>(0)では、関数呼び出しとして使用します。これにより、Test::operator>はメンバー関数として使用され、演算子の特性が失われるため、記述された動作になります ( 「ただし、関数呼び出しで operator-function-id を関数の名前として使用して、明示的に呼び出すことができます。構文」)。

以下も参照してください。

于 2012-11-13T12:21:51.513 に答える
2

少しの間、コンパイラの帽子をかぶってください。一連の明確なルール (演算子の優先順位を含む) に従って、式を解析および評価する必要があります。operator>()式が演算子を使用した場合にも呼び出されるメンバー関数 ( ) の呼び出しが評価に含まれるという事実>- それで何? 特別なケースを作成し、この場合デフォルトの優先順位を変更する必要があると想定しますか? そして、あなたはそれでどこまで行く準備ができていますか? たとえば、このメソッドが間接的に呼び出された場合、または関数ポインターによって呼び出された場合はどうなりますか? 元の質問と同様に、コンパイラのロジックが複雑になり、直感に反する例が可能になると思います。

于 2012-11-13T12:42:35.667 に答える
1

.より()も優先度が高くなります!。演算子の構文は次のように解析されます

(!t) > 0;

明示的な呼び出しは次のように解析されますが、

!((t.operator>)())
于 2012-11-13T12:23:22.430 に答える