swap Functions Should Call swap, Not std::swap

Image

There is one important subtlety in this code: Although it doesn’t matter in this particular case, it is essential that swap functions call swap and not std::swap. In the HasPtr function, the data members have built-in types. There is no type-specific version of swap for the built-in types. In this case, these calls will invoke the library std::swap.

However, if a class has a member that has its own type-specific swap function, calling std::swap would be a mistake. For example, assume we had another class named Foo that has a member named h, which has type HasPtr. If we did not write a Foo version of swap, then the library version of swap would be used. As we’ve already seen, the library swap makes unnecessary copies of the strings managed by HasPtr.

We can avoid these copies by writing a swap function for Foo. However, if we wrote the Foo version of swap as:

void swap(Foo &lhs, Foo &rhs)
{
    // WRONG: this function uses the library version of swap, not the HasPtr version
    std::swap(lhs.h, rhs.h);
    // swap other members of type Foo
}

this code would compile and execute. However, there would be no performance difference between this code and simply using the default version of swap. The problem is that we’ve explicitly requested the library version of swap. However, we don’t want the version in std; we want the one defined for HasPtr objects.

The right way to write this swap function is:

void swap(Foo &lhs, Foo &rhs)
{
    using std::swap;
    swap(lhs.h, rhs.h); // uses the HasPtr version of swap
    // swap other members of type Foo
}

Each call to swap must be unqualified. That is, each call should be to swap, not std::swap. For reasons we’ll explain in § 16.3 (p. 697), if there is a type-specific version of swap, that version will be a better match than the one defined in std. As a result, if there is a type-specific version of swap, calls to swap will match that type-specific version. If there is no type-specific version, then—assuming there is a using declaration for swap in scope—calls to swap will use the version in std.

Very careful readers may wonder why the using declaration inside swap does not hide the declarations for the HasPtr version of swap6.4.1, p. 234). We’ll explain the reasons for why this code works in § 18.2.3 (p. 798).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.246.148