関数のオーバーロードが失敗する:なぜこれらの演算子が衝突したのか?

StackOverflow https://stackoverflow.com/questions/211376

質問

エンジンとアプリケーションという2つの主要な名前空間を含む大きな大きなコードベースがあります。

エンジンはvector3クラスを別のvector3クラスのtypedefとして定義します。vector3クラスではなく、エンジンのネームスペースにある等価演算子を使用します。また、アプリケーションの名前空間に等値演算子を含むクラスをアプリケーションに追加しました。

コンパイルしようとしたとき、適切ではない等価演算子が見つからなかったため、無関係であるが近くのvector3比較は失敗しました。競合が発生しているのではないかと疑ったため、等値演算子を追加したクラスに移動し、コンパイルに成功しました。

// engine.h
namespace Engine
{
    class Vector3Impl { ... };
    typedef Vector3Impl Vector3;
    bool operator==(Vector3 const &lhs, Vector3 const &rhs) { ... }
}


// myfile.cpp
#include "engine.h"

namespace application
{
    class MyClass { ... };
    bool operator==(MyClass const &lhs, MyClass const &rhs) { ... }

    void myFunc(...)
    {
        if ( myClassA == myClassB ) { ... } // builds
    }

    void anotherFunc(...)
    {
        Engine::Vector3 a, b;
        ...
        if ( a == b ) { ... } // fails
    }
}

しかし、それについて考えた後、コンパイルが失敗した理由がわかりません。 vector3sから私のクラスへ、またはその逆への暗黙的な変換はなく、引数に依存するルックアップは、エンジン名前空間から等値演算子をプルして、一致させる必要があります。

サンプルC ++プロジェクトでこのバグを再現しようとしましたが、それは壊れません。この大きな問題を引き起こしている大きな大きなコードベースに何かがあるはずですが、どこから探し始めればいいのかわかりません。不正な「エンジンを使用する」の反対のようなものですか?誰でもアイデアはありますか?

役に立ちましたか?

解決

C ++標準、3.4.4.2宣言:

  

関数呼び出しの各引数タイプTには、0個以上の関連する名前空間のセットと0個のセットがあります   考慮される関連クラス以上。名前空間とクラスのセットは、次のタイプによって完全に決定されます。   関数の引数(およびテンプレートテンプレートの引数の名前空間)。 Typedef名とusing宣言   このセットに貢献しないタイプを指定するために使用されます

ADLはtypedefで動作しません。

他のヒント

以前、引数依存ルックアップ(Koenigルックアップ-@igorに感謝)を持たないコンパイラで同じ問題に遭遇しました(VC6と思います)。これは、演算子を見つけると、それが囲んでいる名前空間を調べるだけであることを意味します。

では、使用しているコンパイラを教えてください。

別のコンパイラに移動すると解決しました。

非常に不便です。

bool operator==(Vector3 const &lhs, Vector3 const &rhs) { ... }

クラスで定義された等値演算子の標準的な定義には、rhsという1つの引数のみが必要です。 lhsはこれです。 ただし、これが問題の解決策になるかどうかはわかりません。

これは私が書くものです:

クラスVector3 {  bool operator ==(const Vector3& rhs)const {...} };

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top