0

In the standard library, if a class type has a specialized swap algorithm, then it will have a member function swap and a free function swap that simply forwards to the member function. I don't quite get the rationale behind having both of them (and thus code duplication) but not just the free function one. Note that, when I say the free function, I take to mean the specialized free swap function, not the generic std::swap function template. Such a specialized function may have privileged access to the relevant class by being a friend of it.

I have two points to support just leaving the free function rather than the member function. First, it forms a more generic swap interface to facilitate writing generic algorithms, for non-class types like arrays cannot have member functions. Second, swap is a binary operation involving two operands and demonstrates a sense of symmetry. It's more natural and intuitive to perform swap using a free function that does not have bias on either operand. For this reason, I have always felt somewhat weird when using the member function swap as if I was performing some operation that is based on the invoking object.

Lingxi
  • 14,579
  • 2
  • 37
  • 93

1 Answers1

3

The free function cannot see the private guts of the class, so the actual functionality needs to be provided as a class member. However, you want the free function because it's a customization point (using ADL); so a generic algorithm will call the free swap in order to achieve whatever swapping is appropriate for the type at hand.

The member function is also useful for constructions like T().swap(existing_thing), since the free function requires lvalue arguments.

I suppose the alternative would have been to make swap a public friend function declared inside the class, which could be found via ADL just as well.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • The specialized free swap function may have privileged access to the class by declaring it as a friend. Besides, I don't see the usefulness of constructions like `T().swap(existing_thing)` when you can simply and more readably clear `existing_thing`. – Lingxi Oct 11 '15 at 16:01
  • 2
    @Lingxi: Clearing holds on to the allocation; swapping with an empty thing does not. – Kerrek SB Oct 11 '15 at 16:14
  • If such usage is to be supported, one can just design the specialized free function to take a universal reference type. – Lingxi Oct 11 '15 at 16:26