函数重载失败:为什么这些运算符会发生冲突?
我有一个很大的代码库,其中包括两个主要名称空间:引擎和应用程序。
引擎将一个 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
}
}
然而经过思考,我不明白为什么编译失败。 没有从 vector3 到我的类的隐式转换,反之亦然,并且依赖于参数的查找应该从引擎名称空间中提取相等运算符并进行匹配。
我已经尝试在示例 C++ 项目中重现此错误,但它拒绝破坏。 庞大的代码库中一定有某些东西导致了这个问题,但我不知道从哪里开始寻找。 类似于流氓“使用引擎”的反面? 有人有什么想法吗?
I've got a big big code base that includes two main namespaces: the engine and the application.
The engine defines a vector3 class as a typedef of another vector3 class, with equality operators that sit in the engine namespace, not in the vector3 class. I added a class to the application that also had equality operators in the application namespace.
When I tried to compile, unrelated but near-by vector3 comparisons failed because it couldn't find an appropriate equality operator. I suspected I was causing a conflict so moved my equality operators into the class I added, and the compile succeeded.
// 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
}
}
However after thinking about it I can't see why the compile failed. There are no implicit conversions from vector3s to my class or vice-versa, and argument-dependent look-up should be pulling in the equality operator from the engine namespace and matching it.
I've tried reproducing this bug in a sample C++ project but that refuses to break. There must be something in the big big code base that is causing this problem, but I'm not sure where to start looking. Something like the opposite of a rogue "using Engine"? Anyone got any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
C++ 标准,3.4.4.2 声明:
ADL 不适用于 typedef。
C++ Standard, 3.4.4.2 declares:
ADL doesn't work with typedef's.
我曾经遇到过同样的问题,编译器没有参数依赖查找(Koenig Lookup - 感谢@igor)(我认为是 VC6)。 这意味着当它看到一个运算符时,它只是在封闭的命名空间中查找。
那么你能告诉我们你使用什么编译器吗?
转移到另一个编译器解决了它。
确实非常不方便。
I once ran into the same problem with a compiler that didn't have Argument Dependent Lookup (Koenig Lookup - thanks @igor) (VC6 I think). This means that when it sees an operator, it just looks in the enclosing namespaces.
So can you tell us what compiler you use?
Moving to another compiler solved it.
Very inconvenient indeed.
在类上定义的相等运算符的规范定义应该只有一个参数,即 rhs。 lhs是这样的
不知道这是否能解决您的问题。
这就是我要写的:
class Vector3 {
bool 运算符 ==( const Vector3 & rhs) const { ... }
};
The canonical definition of an equality operator defined on a class should only have one argument, namely the rhs. The lhs is this.
Don't know if this would be a solution to your problem though.
This is what I would write :
class Vector3 {
bool operator==( const Vector3 & rhs) const { ... }
};