二元运算符的最佳命名空间是什么?

时间:2016-01-08 11:26:43

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

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

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

我有类似的东西,

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

我想" stream" 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<<因为,在其他条件相同的情况下,似乎直观地更喜欢namespace ns_B。)

编辑:这是我在命名空间的实际使用中可以找到的最完整的指南和参考 https://www.google.com/amp/s/akrzemi1.wordpress.com/2016/01/16/a-customizable-framework/amp/

3 个答案:

答案 0 :(得分:5)

在案例1中,很容易:将其放在您控制的namespace中。

在案例2中,它取决于您的选择:无论什么看似更合乎逻辑。在您的示例中,我更喜欢ns_B

唯一棘手的情况是3.你不应该真正添加namespace。如果你想要新的胶水&#39;功能作为您自己的第三个namespace mine的一部分,然后自然地将其放在那里,mine中对该功能的任何使用都将自动解决。当然,这不会占用ADL,但不需要它,因为您只需要在mine内使用新功能,而不是在其他地方。

答案 1 :(得分:4)

您可以将您的运算符放在任一名称空间中,它将起作用。作为最佳实践,请将其放在属于您的代码的命名空间中。

答案 2 :(得分:2)

我的建议:不要使用任何命名空间。 .closest('li')中的代码本身并不知道ns_A中存在任何内容 - 它不依赖于它;因此,ns_Ans_B构造的代码不属于ns_A。对称性ns_A也是如此。

您的ns_B应位于operator<<ns_A中的“最不常见的命名空间”中,这可能不是命名空间(但如果ns_Bns_A然后ns1::ns2ns_B,然后使用ns1::ns3)。

在我看来,强制代码进入名称空间并不明显属于它,并不优雅,从概念上打破了封装。至于ADL,我认为你不应该期望ns1ns_A的“最不常见的命名空间”给你带来的东西。