为什么在地图上隐式==&lt; <int,myclass>不能编译?</int,myclass>

时间:2013-09-01 10:52:52

标签: c++ c++11 operators

我有一个奇怪的问题,为我的一个班级定义==。 我将这里的代码简化为我在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 == reference on cppreference.com

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

提前谢谢。

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

[溶液] 如果我将操作符模式化到命名空间,它就可以工作:

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

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

2 个答案:

答案 0 :(得分:7)

根据您的描述,我 guess 您的等式运算符未在与您的类相同的命名空间中定义。以下说明了这种情况:

#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
}

显而易见的解决方法是在与类相同的命名空间中定义相等运算符。它不起作用的原因是模板中的两阶段名称查找:当模板被实例化时,它只进行第二阶段名称查找,即,它只根据显式限定或参数查找与模板参数相关的函数依赖查找。等于运算符在std::map<K, V>中不合格(好吧,使用运算符表示法调用它时它永远不合格),因此需要通过参数依赖查找来找到它。

答案 1 :(得分:3)

您的MyClass::operator==需要标记为const。例如:

bool operator ==(const MyClass&) const;

请注意您的运营商:

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

不起作用。 operator==只接受一个参数并比较this和传递的参数。

除非它不是类成员运营商,而是非会员运营商。在这种情况下,它是正确的,应该工作。因为它没有,它告诉我你忘了#include声明运算符的头文件。