What is the best namespace for a binary operator?
Asked Answered
F

3

10

For elegance, encapsulation and to exploit ADL (Argument Dependent Lookup) is common to define a function inside the namespace of the function argument.

Suppose I have two libraries in different namespace. There are three cases 1) one is part of a library I control and the other is third party (for example Boost), or 2) I control both, or 3) I control none (just writing "glue" code).

I have something like this,

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

I want to "stream" B in to A, what is the best option

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

or should I put it in both namespaces?

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

Which is the best namespace to define a binary function like this?

(Does C++11's namespace inline change any recommendation?)

(I use the example operator<< because, other things being equal it seems intuitively be better to prefer namespace ns_B.)


EDIT: this is the most complete guide and reference I could find on real use of namespaces https://www.google.com/amp/s/akrzemi1.wordpress.com/2016/01/16/a-customizable-framework/amp/

Fastening answered 8/1, 2016 at 11:26 Comment(2)
Don't fiddle with namespace that you do not control.Amaranthaceous
@Walter, apparently that recommendation is good for Std. But apparently good solutions actually fiddle with other's namespaces google.com/amp/s/akrzemi1.wordpress.com/2016/01/16/…Fastening
A
5

In case 1, it is easy: put it in the namespace that you control.

In case 2, it's up to your choice: whatever appears more logical. In your example case, I would prefer ns_B.

The only tricky situation is 3. You shouldn't really add to either namespace. If you want the new 'glue' functionality as part of your own third namespace mine, then naturally put it in there and any use of that functionality within mine will be automatically resolved. Naturally, this will not envoke ADL, but there is no need for it, since all you want is to use the new functionality within mine, not somewhere else.

Amaranthaceous answered 8/1, 2016 at 11:34 Comment(0)
I
4

You can put your operator in either namespace and it will work. As a best practice, put it in the namespace that belongs to your code.

Innutrition answered 8/1, 2016 at 11:33 Comment(0)
S
2

My suggestion: Don't use any of the namespaces. Code in ns_A is not aware, in itself, of the existence of anything in ns_A - it doesn't depend on it; so code regarding both ns_B and ns_A constructs does not belong in ns_A. The same is true for ns_B, by symmetry.

Your operator<< should be in the "least common namespace" among ns_A and ns_B, which is probably no namespace (but if ns_A is ns1::ns2 and ns_B is ns1::ns3 then use ns1).

Forcing code into a namespace it does not clearly belong in is, in my opinion, not elegant and breaks encapsulation, conceptually. As for ADL, I think you should not expect more than what the "least common namespace" of ns_A and ns_B gives you.

Sponson answered 8/1, 2016 at 16:21 Comment(1)
Bold recommendation certainly. This is an option to consider. The best part, the good things about ADL will keep working.Fastening

© 2022 - 2024 — McMap. All rights reserved.