1

エンジンとアプリケーションという 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++ プロジェクトでこのバグを再現しようとしましたが、壊れません。この問題を引き起こしている大きな大きなコード ベースに何かがあるに違いありませんが、どこから調べればよいかわかりません。ローグの「エンジンを使う」の逆みたいなもの?誰でもアイデアはありますか?

4

3 に答える 3

2

C++ 標準、3.4.4.2 では次のように宣言されています。

関数呼び出しの引数の型 T ごとに、0 個以上の関連付けられた名前空間のセットと、考慮される 0 個以上の関連付けられたクラスのセットがあります。名前空間とクラスのセットは、関数の引数の型 (およびテンプレート テンプレート引数の名前空間) によって完全に決定されます。型を指定するために使用される typedef 名と using-declarations は、このセットには寄与しません

ADL は typedef では機能しません。

于 2008-10-17T08:36:25.693 に答える
0

Argument Dependent Lookup (Koenig Lookup - @igor に感謝) (VC6 だと思います) を持たないコンパイラで同じ問題に遭遇したことがあります。これは、演算子を検出すると、囲んでいる名前空間だけを参照することを意味します。

では、使用しているコンパイラを教えていただけますか?

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

確かに非常に不便です。

于 2008-10-17T08:35:17.473 に答える
-1
bool operator==(Vector3 const &lhs, Vector3 const &rhs) { ... }

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

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

class Vector3 { bool operator==( const Vector3 & rhs) const { ... } };

于 2008-10-17T08:17:24.577 に答える