操作符在不同命名空间时的模糊重载

时间:2013-09-12 12:06:36

标签: c++ namespaces overloading ambiguous

文件A.hpp:

struct foo
{
   int x;
} foo;

inline bool operator ==(const foo &lhs, const foo &rhs)
{
   /* ... */
}

文件B.hpp

#include "A.hpp"

namespace SomeNamespace
{
   bool operator==(const foo &lhs, const foo &rhs)
   {
      /* ... */
   }

   /* ... */
   void someFunction(const foo &foo_instance1, const foo &foo_instance2)
   {
      CPPUNIT_ASSERT(foo_instance1 == foo_instance2);
   }
}

ASSERT行的编译器错误是:

error: ambiguous overload for 'operator==' ...

所以,问题是编译器会看到两个比较运算符。

A.hpp的全局命名空间中的定义和B.hpp的SomeNamespace中的定义是不明确的。

为什么编译器不在SomeNamespace中使用defintion?

2 个答案:

答案 0 :(得分:2)

你已经两次定义了相同的功能;你期待什么 发生?编译器找到SomeNamespace::operator== 不合格的名称查找,以及::operator==与ADL。以来 两者都有完全相同的签名,没有办法了 编译器选择一个而不是另一个。

作为一般规则,类型的重载运算符应该是 在与类型相同的命名空间中定义,而在其他位置没有。 (如果重载运算符采用两种不同的类型,则定义 在两个不同的命名空间中,我将运算符放在全局中 命名空间。但这种情况很少见。)

答案 1 :(得分:2)

在您的程序中operator==在全局命名空间和Somenamespace中定义。

因此,当您尝试访问operator==时,编译器无法解析要调用的函数,因为两个函数都具有相同的签名,并且编译器都可以看到这两个函数。

因此,要使用SomeNamespace中定义的operator==,您必须使用SomeNamespace::operator==,并且对于全局命名空间中的运算符定义,您必须使用::operator==