【问题标题】:What is the best namespace for a binary operator?二元运算符的最佳命名空间是什么?
【发布时间】:2016-04-13 01:43:09
【问题描述】:

为了优雅、封装和利用 ADL (Argument Dependent Lookup),通常在函数参数的命名空间内定义函数。

假设我在不同的命名空间中有两个库。有三种情况 1)一种是我控制的库的一部分,另一种是第三方库(例如 Boost),或 2)我控制两者,或 3)我不控制(只是编写“胶水”代码)。

我有这样的东西,

namespace ns_A{
   struct A{...}; // something that looks like iostream
}
namespace ns_B{
   struct B{...};
}

我想将 B “流”到 A 中,最好的选择是什么

namespace ???{ // what is more correct ns_A, or ns_B?
   A& operator<<(A& a, B const& b){...} 
}

或者我应该把它放在两个命名空间中?

namespace ns_B{
   A& operator<<(A& a, B const& b){...} 
}
namespace ns_A{
   using ns_B::operator<<;
}

定义这样的二进制函数的最佳命名空间是什么?

(C++11 的命名空间内联会改变任何建议吗?)

(我使用示例 operator&lt;&lt; 是因为,在其他条件相同的情况下,似乎直觉上更喜欢 namespace ns_B。)


编辑:这是我能找到的关于真正使用命名空间的最完整的指南和参考资料 https://www.google.com/amp/s/akrzemi1.wordpress.com/2016/01/16/a-customizable-framework/amp/

【问题讨论】:

标签: c++ c++11 argument-dependent-lookup


【解决方案1】:

在第一种情况下,很简单:把它放在你控制的namespace 中。

在第 2 种情况下,由您选择:任何看起来更合乎逻辑的。在你的例子中,我更喜欢ns_B

唯一棘手的情况是 3。你不应该真正添加到 namespace 中。如果您希望新的“胶水”功能作为您自己的第三个namespace mine 的一部分,那么自然地把它放在那里,在mine 中对该功能的任何使用都会自动解决。当然,这不会调用 ADL,但没有必要这样做,因为您只想使用 mine 中的新功能,而不是其他地方。

【讨论】:

    【解决方案2】:

    你可以将你的操作符放在任何一个命名空间中,它都会起作用。作为最佳实践,请将其放在属于您的代码的命名空间中。

    【讨论】:

      【解决方案3】:

      我的建议:不要使用任何命名空间。 ns_A 中的代码本身并不知道 ns_A 中是否存在任何东西——它不依赖于它;所以关于ns_Bns_A 构造的代码不属于ns_Ans_B 也是如此,对称性。

      您的operator&lt;&lt; 应该在ns_Ans_B 中的“最少公共命名空间”中,这可能没有命名空间(但如果ns_Ans1::ns2ns_Bns1::ns3,那么使用ns1)。

      在我看来,将代码强制放入它不明确属于的命名空间是不优雅的,并且在概念上会破坏封装。至于 ADL,我认为你不应该期望超过 ns_Ans_B 的“最不常用命名空间”给你的东西。

      【讨论】:

      • 当然是大胆的推荐。这是一个需要考虑的选项。最好的部分是,ADL 的优点将继续发挥作用。
      猜你喜欢
      • 1970-01-01
      • 2010-10-24
      • 2013-11-18
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多