我有一个奇怪的问题,为我的一个班级定义==。 我将这里的代码简化为我在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);
但我不知道为什么我需要这样做,是否在语言定义中? (我猜是的)
答案 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
声明运算符的头文件。