5

我有一个奇怪的问题,为我的一个班级定义 ==。我将此处的代码简化为我在 Visual 2013 上测试的示例; MyClass 在命名空间 N 中定义

这确实编译:

N::MyClass a, b;
bool test = a == b;

这个也是:

const N::MyClass a, b;
bool test = a == b;

这不编译

std::map<int, N::MyClass> a, b;
bool test = a == b;

供您参考, == 运算符声明如下:

bool operator==(const N::MyClass & a, const N::MyClass & b);

这是我得到的错误:error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const MyClass' (or there is no acceptable conversion)

但据我所知,map 运算符是定义的:map == reference on cppreference.com

有人可以解释一下为什么这是错误的吗?

先感谢您。

我没有找到答案,如果这是愚蠢的,我很抱歉。

[解决方案] 如果我将操作员模式化到命名空间中,它可以工作:

bool N::operator==(const MyClass & a, const MyClass & b);

但我不知道为什么我需要这样做,是在语言定义中吗? (我猜是)

4

2 回答 2

7

Based on your description, I guess your equality operator is not defined in the same namespace as your class. The following demonstrates the situation:

#include <map>

namespace foo
{
    class bar
    {
    };
}

using namespace foo;
bool operator== (bar const&, bar const&) { return true; }

int main()
{
    bar const b;
    b == b; // OK
    std::map<int, bar> mb;
    mb == mb; // ERROR
}

The obvious fix is to define the equality operator in the same namespace as the class. The reason it doesn't work is the two-phase name look-up in templates: when a templates is instantiated it only does second phase name look-up, i.e., it only finds functions relating to template arguments based on explicit qualification or argument dependent look-up. The equality operator isn't qualified in std::map<K, V> (well, it is never qualified when using operator notation to call it) and, thus, it needs to be found by argument dependent look-up.

于 2013-09-01T12:14:38.597 回答
3

Your MyClass::operator== needs to be marked const. For example:

bool operator ==(const MyClass&) const;

Note that your operator:

bool operator==(const MyClass & a, const MyClass & b);

will not work. operator== only takes one argument and compares this and the passed argument.

Unless it's not a class member operator, but a non-member one. In this case, it's correct and should work. Since it doesn't, it suggests to me that you forgot to #include the header file where your operator is declared.

于 2013-09-01T11:05:44.373 回答