1

我有一个很大的代码库,其中包括两个主要的命名空间:引擎和应用程序。

引擎将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,有一组零个或多个关联的命名空间和一组零个或多个关联的类需要考虑。命名空间和类的集合完全由函数参数的类型(以及任何模板模板参数的命名空间)决定。用于指定类型的 Typedef 名称和 using-declarations 不构成此集合

ADL 不适用于 typedef。

于 2008-10-17T08:36:25.693 回答
0

我曾经在没有参数依赖查找(Koenig Lookup - 感谢@igor)(我认为是VC6)的编译器上遇到同样的问题。这意味着当它看到一个操作符时,它只是在封闭的命名空间中查找。

那么你能告诉我们你使用什么编译器吗?

转移到另一个编译器解决了它。

确实很不方便。

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

在类上定义的等式运算符的规范定义应该只有一个参数,即 rhs。lhs是这样的。不知道这是否可以解决您的问题。

这就是我要写的:

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

于 2008-10-17T08:17:24.577 回答