3

For a class in a namespace the proper way to provide swap() is to define a free function in that namespace (e.g. How to overload std::swap()). But what is the best practice for a class that's in the global namespace?

cppreference has an example with a free swap() function in the global namespace.
But this is the only place I've seen that done and I worry this was just an oversight.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Dan Stahlke
  • 1,417
  • 1
  • 15
  • 20
  • The "global namespace" is simply the namespace named `::` (i.e. no preceding namespace name to reference names in the namespace). So the technique is the same as for placing in any other namespace, except that the namespace name does not need to be specified. – Peter Apr 19 '19 at 00:14
  • The example showed an overloaded function with the arguments being the custom class, just like `operator<<()`. Given that, I don't think it would hurt, but I'm not an expert in best practices. –  Apr 19 '19 at 00:17

2 Answers2

2

In general, no library should use the global namespace, only the main application. And even that rarely, who knows when you will make part of it its own library?

Aside from that, the global scope :: is a namespace like any other, thus if you define a type there, the associated free functions belong there too.
Otherwise, argument-dependent lookup cannot find them.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • I agree that no library *should* put functions in the global namespace. But this one does, and it's part of the public API, so we're stuck with it being this way. – Dan Stahlke Apr 19 '19 at 00:20
  • Backwards-compatibility and external reality generally trumps those rules for good code, yes. Thus only *in general*. – Deduplicator Apr 19 '19 at 00:22
0

I think you can just define a swap overload in the same namespace as the class, even if it's in the global namespace. Are you looking for something like this?

#include <iostream>
#include <utility>

struct S {
    void swap(S& other)
    {
        using std::swap;
        swap(data, other.data);
    }
    int data;
};

void swap(S& lhs, S& rhs)
{
    lhs.swap(rhs);
}

int main()
{
    using std::swap;
    S a = { 10 }, b = { 20 };
    std::cout << a.data << ' ' << b.data << std::endl;
    swap(a, b);
    std::cout << a.data << ' ' << b.data << std::endl;
    return 0;
}

Notice the using std::swap in main. So if you comment out the swap overload for the class, the code will fallback to std::swap.

Swoope
  • 3
  • 2