函数重载失败:为什么这些运算符会发生冲突?

发布于 2024-07-07 02:39:22 字数 1027 浏览 7 评论 0原文

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

引擎将一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

み青杉依旧 2024-07-14 02:39:22

C++ 标准,3.4.4.2 声明:

对于函数调用中的每个参数类型 T,有一组零个或多个关联的命名空间和一组零个
或更多要考虑的相关类别。 命名空间和类的集合完全由类型决定
函数参数(以及任何模板模板参数的命名空间)。 Typedef 名称和 using-声明
用于指定不参与此集合的类型

ADL 不适用于 typedef。

C++ Standard, 3.4.4.2 declares:

For each argument type T in the function call, there is a set of zero or more associated namespaces and a set of zero
or more associated classes to be considered. The sets of namespaces and classes is determined entirely by the types of
the function arguments (and the namespace of any template template argument). Typedef names and using-declarations
used to specify the types do not contribute to this set
.

ADL doesn't work with typedef's.

旧情别恋 2024-07-14 02:39:22

我曾经遇到过同样的问题,编译器没有参数依赖查找(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.

纵性 2024-07-14 02:39:22
bool operator==(Vector3 const &lhs, Vector3 const &rhs) { ... }

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

这就是我要写的:

class Vector3 {
bool 运算符 ==( const Vector3 & rhs) const { ... }
};

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

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 { ... }
};

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文