[Effective C + +--025] Consider writing a swap function that does not throw an exception

Source: Internet
Author: User

Introduction

In my last blog, I spoke about the swap function.

The swap is only part of the STL and then becomes the spine of an unusually safe program, and is used to handle the possibility of self-assignment.

One, swap function

The swap function of the standard library is as follows:

1 namespace STD {2     template<typename t>3     void swap (T &a, t& b)  4    {5            T Temp (a); 6             A = b; 7             b = temp; 8     }9 }

As long as the type T supports copying (by copying constructors and copy assignment operators), this version of the SWAP function will help you replace objects of type T.

The swap function in the context of Pimpl

Suppose we have the following classes.

1 classWidgetimpl {2  Public:3     ...4 Private:5     intA,b,c;//There may be a lot of data6std::vector<Double> v;//means replication takes a long time7     ....8 }9 Ten classWidget { One  Public: AWidgets (Constwidget&RHS); -widget&operator= (Constwidget&RHS) -     { the          ..... -*pimpl = *(Rhs.pimpl); -      }   - Private: +widgetimpl*Pimpl; -};

Once the two Widget objects are replaced, the only thing we need to do is displace their pimpl pointers, but one of the swap functions does not know this, it duplicates three widgets and three Widgetimpl, very inefficient!

So the effect we want is: Swap only the Pimpl pointer!

So we can design this idea:

1 namespace STD {2     template<>          //  indicates that it is a special version of Std::swap 3      void swap<widget> (Widget &a, widget& b)4    {5          Swap (A.pimpl, b.pimpl); 6     }7 }

The above code certainly does not compile, because Pimpl is a private member. Maybe you said we could use the friend function to solve the problem, but it's not quite as expected!

Let's wrap it up again:

1 classWidget {2  Public:3     ...4     voidSwap (widget&Other )5     {6         usingStd::swap;7Swap (Pimpl, Other.pimpl);//Displace widgets and replace its pimpl pointer8     }9     ....Ten } One  A namespaceSTD { -Template<>//indicates that it is a special version of Std::swap -     voidSwap<widget> (widget& A, widget&b) the     { - A.swap (b); -     } -}

This is not only compiled, but also consistent with the STL container, as all STL containers are provided with public swap member functions and STD::SWAP special versions.

However, it is important to note that C + + only allows the class templates to be biased, and it is not feasible to special on the function template. The following code is compiled, however.

1 namespace STD {2     template<typename t>         3     void4                          widget<t>& B) 5     {6         swap (A.pimpl, b.pimpl); 7     }8 }

Third, function template partial Special

So, what should we do if we want to be specific on the function template? The answer is to add an overloaded version!

As follows:

1 namespace STD {2     template<typename t>         3     void Swap (widget<t> & A,            //  Note there is no "<Widget<T>>"4               widget<t>&  b)5    {6         swap (A.pimpl, b.pimpl); 7     }8 }

At the same time, we can declare a non-member function in order to get a specific version of the higher version of the template that we provide for other people to call swap!

1 namespaceWidget {2Template<typename t>3     classwidget{....}4     5Template<typename t>6     voidSwap (widget<t>& A,//Note There's no "<Widget<T>>" here .7widget<t>&b)8     {9 swap (A.pimpl, b.pimpl);Ten     } One}

Summary

1. When Std::swap is not efficient for your type, provide a swap member function and make sure that the function does not throw an exception.

2. If you provide a member swap, you should also provide a non-member swap to invoke the former. For classes, please also special std::swap.

3. You should use the using declaration for std::swap when calling swap, and then call swap without any namespace qualification adornments.

4. The std template for "user-defined type" is good, but don't try to add something new to STD in STD

[Effective C + +--025] Consider writing a swap function that does not throw an exception

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.