Possible Duplicate:
Where should non-member operator overloads be placed?
在浏览 SO 时,我经常发现涉及重载/定义 std::ostream& operator<<(std::ostream& os, const Foo& foo)
的问题或答案或 Foo operator+(const Foo& l, const Foo& r)
.
虽然我知道如何以及何时(不)编写这些运算符,但我对 namespace
感到困惑。东西。
如果我有以下类(class):
namespace bar
{
class Foo {};
}
其中namespace
我应该写不同的运算符定义吗?
// Should it be this
namespace bar
{
std::ostream& operator<<(std::ostream& os, const Foo& foo);
}
// Or this ?
namespace std
{
ostream& operator<<(ostream& os, const bar::Foo& foo);
}
// Or this ?
std::ostream& operator<<(std::ostream& os, const bar::Foo& foo);
同样的问题也适用于 operator+
.那么,这里有什么好的做法以及为什么?
最佳答案
规则是,在寻找合适的函数重载时,会同时考虑当前命名空间和参数类型定义的所有命名空间。这称为参数相关查找 (ADL)。
所以当你有这个代码时:
::std::ostream& os = /* something */;
const ::bar::Foo& foo = /* something */;
os << foo;
考虑以下命名空间:
- 当前命名空间
- ::std,因为这里定义了os的类型
- ::bar,因为这里定义了 foo 的类型
因此,您提到的所有三种可能性都将起作用,因此乍一看“足够好”。
但是....
您不能在::std 中定义新函数,因此您不能将重载的运算符放在该命名空间中。 (您可以在::std 中专门化模板,但这不是我们在这里所做的)
其次,“当前命名空间”可能会发生变化,因此如果您将函数定义放在该命名空间中,则可能无法始终找到它。
所以归根结底,重载运算符的最佳放置位置是与 Foo 相同的命名空间:
namespace bar
{
std::ostream& operator<<(std::ostream& os, const Foo& foo);
}
关于c++ - 运算符重载和命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3891402/