我有一个很大的代码库,包括两个主要的命名空间:引擎和应用程序。
引擎将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 ++项目中重现此错误,但拒绝破解。大型代码库中必定存在导致此问题的内容,但我不确定从哪里开始查找。像流氓“使用引擎”的对立面?有人有任何想法吗?
答案 0 :(得分:2)
C ++标准,3.4.4.2声明:
对于函数调用中的每个参数类型T,有一组零个或多个关联的命名空间和一组零 或更多相关类别。命名空间和类的集合完全由类型决定 函数参数(以及任何模板模板参数的命名空间)。 Typedef名称和使用声明 用于指定对此集合没有贡献的类型。
ADL不适用于typedef。
答案 1 :(得分:0)
我曾经遇到过与没有Argument Dependent Lookup的编译器相同的问题(Koenig Lookup - 感谢@igor)(我认为是VC6)。这意味着当它看到一个运算符时,它只是查看封闭的命名空间。
那么你能告诉我们你使用什么编译器吗?
转移到另一个编译器解决了它。
非常不方便。
答案 2 :(得分:-1)
bool operator==(Vector3 const &lhs, Vector3 const &rhs) { ... }
在类上定义的等于运算符的规范定义应该只有一个参数,即rhs。这是lhs。 不知道这是否可以解决您的问题。
这就是我要写的:
class Vector3 { bool运算符==(const Vector3& rhs)const {...} };