c++ - 运算符重载和命名空间

标签 c++ namespaces operator-overloading operator-keyword

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/

相关文章:

c++ - 在析构函数中检测事件异常

c++ - (c++) 可以从外部来源嵌套命名空间

php - Psr-4 : namespace and spl autoload

c++ - QPID C++ 客户端是否支持使用 RabbitMQ 代理进行 SSL channel 加密

c++ - 使用 C++ 动态分配结构数组

docker - 无法更新快照命名空间 : cannot create symlink in "/etc/docker": existing file in the way

C++ 一元 - 运算符重载无法编译

C++ 复数运算符重载

C++ 实例化与类中的函数不同的类

c++ - _dl_runtime_resolve -- 共享对象何时加载到内存中?