Namespaces and Operator Overloading in C++
Asked Answered
T

3

42

When authoring a library in a particular namespace, it's often convenient to provide overloaded operators for the classes in that namespace. It seems (at least with g++) that the overloaded operators can be implemented either in the library's namespace:

namespace Lib {
class A {
};

A operator+(const A&, const A&);
} // namespace Lib

or the global namespace

namespace Lib {
class A {
};
} // namespace Lib

Lib::A operator+(const Lib::A&, const Lib::A&);

From my testing, they both seem to work fine. Is there any practical difference between these two options? Is either approach better?

Threatt answered 5/10, 2008 at 11:58 Comment(1)
Possible duplicate of Namespaces and operator resolutionDerangement
M
41

You should define them in the library namespace. The compiler will find them anyway through argument dependant lookup.

No need to pollute the global namespace.

Mistrot answered 5/10, 2008 at 12:3 Comment(1)
Another reason for using the library namespace: this post contains an example where using the global namespace doesn't work.Sclaff
A
17

Putting it into the library namespace works because of Koenig lookup.

Allonym answered 5/10, 2008 at 12:21 Comment(1)
Indeed Koeing look-up was created exactly so you could put the function inside the Lib namespace, and still have it overload correclty. See Exceptional C++ Items 31-32.Timely
B
3

You should define it in the namespace, both because the syntax will be less verbose and not to clutter the global namespace.

Actually, if you define your overloads in your class definition, this becomes a moot question:

namespace Lib {

class A {
public:
    A operator+(const A&);
};

} // namespace Lib
Benton answered 5/10, 2008 at 12:20 Comment(2)
This can be a bad idea, since it means that if B can be implicitly converted to A but is not a subclass of A, then A+B works, but B+A confusingly doesn't. Of course that doesn't necessarily matter, for example if your house style bans implicit conversion between user-defined types anyway.Hrvatska
I agree: There is the problem that A+B works, but not B+A (say A is a class simulating a complex number, and B an int). Another problem is that a non friend operator + functions increase the encapsulation of the class, whereas the class method decreases it.Crooked

© 2022 - 2024 — McMap. All rights reserved.