Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 运算符在不同名称空间中时的重载不明确_C++_Namespaces_Overloading_Ambiguous - Fatal编程技术网

C++ 运算符在不同名称空间中时的重载不明确

C++ 运算符在不同名称空间中时的重载不明确,c++,namespaces,overloading,ambiguous,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) { /* ...

文件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);
   }
}
带有断言的行的编译器错误为:

error: ambiguous overload for 'operator==' ...
因此,问题是编译器同时看到两个比较运算符

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


为什么编译器不使用SomeNamespace中的定义?

您已经定义了两次相同的函数;你期望得到什么 发生编译器使用查找
SomeNamespace::operator==
非限定名称查找,并使用ADL执行
::operator=
。自从 两者都有完全相同的签名,没有办法 编译器选择其中一个

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

您已经定义了两次相同的函数;你期望得到什么 发生编译器使用查找
SomeNamespace::operator==
非限定名称查找,并使用ADL执行
::operator=
。自从 两者都有完全相同的签名,没有办法 编译器选择其中一个

一般来说,类型的重载运算符应该是 在与类型相同的命名空间中定义,而不在其他地方定义。 (如果重载运算符采用两种不同的类型,则定义 在两个不同的名称空间中,我将操作符放在全局
在你的程序中,
操作符==
是在全局名称空间和Somenamespace中定义的

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


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

operator=
在全局命名空间和SomeNamespace中定义

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



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

,否则它不会发生。。。。?提问时请尝试提供。抱歉,已通过编辑更正。请问
foo
在哪里声明?或者它没有发生。而
foo_instance1
是。。。。?问问题时请尽量提供一个。抱歉,用edit更正。那么
foo
声明在哪里?我不知道ADL也在全局范围内(如果这是你的意思的话?)@JamesKanze你能解释一下区别吗?好的,可以看出ADL是实际的“问题”,因为foo和它的==运算符是在同一个(全局)中定义的命名空间。因此,此定义也被视为“本地”命名空间中的定义。Thx@PetrBudnik区别是什么?@jrok ADL在参数所隐含的名称空间中查找;在本例中,它在全局名称空间中查找,因为这是定义
foo
的地方。我不知道ADL也在全局范围中查找(如果这是您的意思的话?)@JamesKanze您能解释一下区别吗?好的,请看一下ADL是实际的“问题”,因为foo及其==运算符是在同一个(全局)名称空间中定义的。因此,此定义也被视为“本地”命名空间中的定义。Thx@PetrBudnik区别是什么?@jrok ADL在参数所隐含的名称空间中查找;在本例中,它在全局名称空间中查找,因为在全局名称空间中定义了
foo
?我认为SomeNamespace中的运算符==应该首先被考虑,因为它应该首先被找到。难道编译器不是以自下而上的方式搜索名称(名称空间)并在找到第一个正确的定义时停止吗?这不是自上而下或自底向上。当您编译代码编译器时,两个函数“同时”可见。@shobi您能解释一下区别吗?@Juergen请参考此@PetrBudnik抱歉,我没有得到您。查找规则是什么?我认为SomeNamespace中的运算符==应该首先被考虑,因为它应该首先被找到。难道编译器不是以自下而上的方式搜索名称(名称空间)并在找到第一个正确的定义时停止吗?这不是自上而下或自底向上。当你在编译代码编译器时,两个函数“同时”可见。@shobi你能解释一下区别吗?@Juergen请参考这个@PetrBudnik抱歉,我没有得到你。