Effective C + + clause 25 Consider writing out a swap function that does not throw an exception

Source: Internet
Author: User

1. Swap is a part of the STL and later becomes an important spine of the exception-safe programming (Exception-safe programming) (see Clause 29), the SWAP function template definition for the standard library is similar to the following:

namespace std{    template<typename t>    swap (t& lhs,t& rhs) {        T temp (LHS);        LHS=RHS;        RHS=temp;}    }
View Code

As long as the T type supports copy construction and copy assignment, the standard library swap function calls the copy constructor of T and the conversion of the copy construction operator to complete the value, but for some classes, this default conversion is too expensive, such as:

class demo{public:    Demo (const demo&);    Demooperator= (const demo& RHS        ) {... *ptr=*rhs.ptr;        ...    }    ... Private :    vector<int>* ptr;}
View Code

If the default behavior of the standard library swap is expensive, you can actually replace the address of two pointers.

2. One way to resolve 1 is to make the swap function template in the standard library STD namespace special, as follows:

namespace std{    template<>    void swap<demo> (demo& lhs,demo& rhs) {        swap ( LHS.PTR,RHS.PTR);}    }
View Code

Normally we cannot change things in the Std namespace of the standard library, but C + + allows for the creation of a special version for standard templates, so the above code is theoretically feasible, but because the PTR member of the demo is set to private, So the above code does not compile. We can declare a public member function called Swap for the demo to perform the related operation, and then make the standard KUT swap call the function, as follows:

class demo{public    : ...     void Swap (demo& rhs) {        using  std::swap;        Swap (PTR,RHS.PTR);    }    ...} namespace std{    void swap (demo& lhs,demo& rhs) {        lhs.swap (RHS);    }}
View Code

This approach is not only compiled, but also consistent with STL because "all STL containers are provided with public member functions and STD::SWAP-specific versions"

If the demo is a class template, the situation will change, for example:

Template<typename t>class demo{...}

It is possible to define a swap member function within the Demo class template if you want to use the above method, but it is necessary to std::swap the Times:

namespace std{    template<typename t>    void swap<demo<t> > (demo<t>& lhs, demo<t>& RHS) {        lhs.swap (RHS);    }}
View Code

The result is not compiled, because the C + + standard currently only allows the class templates to be biased, and does not allow the function templates to be biased (note: biasing refers to a template is special to another template, For example, partial type parameter specificity and type parameters are special to container type parameters (as above))

Another way is to add an overloaded version for Std::swap, as follows:

namespace std{    template<typename t>    void swap (demo<t>& lhs,demo<t>& RHS) {// Note there is no swap after <>, so this is not a special         Lhs.swap (RHS);    }}
View Code

Unfortunately, this is also not compiled, because C + + allows the standard library templates to be customized, "but you can't add new templates (or classes or functions or anything else)" into Std.

There is also a way to declare a non-member swap to make it call member swap, but instead of declaring that non-member as a special or overloaded version of Std::swap, it is placed in another namespace Demostuff, as follows:

namespace demostuff{...    Template<typename t>    class  demo{...}    ...    Template<typename t>    void swap (demo<t>& lhs,demo<t>& RHS) {        Lhs.swap (RHS);    }}
View Code

Of course, the above can also be declared within the global namespace, but this may cause a messy scope (in the effective C + + Chinese version, to maintain "decent and moderate").

3. Assume for the following functions:

Template<typename t>void dosomething{t& lhs,t& rhs) {    ...    Swap (LHS,RHS);    ...}
View Code

If you want to invoke the exclusive swap version of T and call the generalized version within STD without the stupidity, you can define it as follows:

Template<typename t>void dosomething{t& lhs,t& rhs) {    using  std:: Swap;    ...    Swap (LHS,RHS);    ...}
View Code

"Once the compiler sees a call to swap, they look for the appropriate swap and call it." The name lookup rule for C + + (name lookup roles) ensures that any exclusive swap of t within the global scope or the namespace where T resides is found. " If T is not in the Demostuff namespace, the compiler uses the argument-by-lookup rule (argument-dependent Lookup) to find the swap within the demostuff. " If there is no dedicated swap present, the compiler calls the swap within Std. (using Std::swap does not specify that the swap is within the STD version, but that the swap within the STD is visible within the function, if called by "Std::swap (OBJ1,OBJ2)", the call must be in STD version)

3. Member edition (refers to the above high-efficiency version) Swap must never throw an exception! As mentioned above, an important application of swap is "help classes (or class templates) provide strong exception security (exception-safety) protection", However, this technique applies only to the member version (high-efficiency version), because the default version of swap calls the copy constructor and copy assignment operators, both of which allow exceptions to be thrown. Therefore, for custom efficient versions, it is often not just a way to efficiently displace values, but an exception is not thrown. " In general, these two swap characteristics are linked because efficient swap is always based on the operation of the built-in type, and the operation on the built-in type never throws an exception ".

Effective C + + clause 25 Consider writing out a swap function that does not throw an exception

Related Article

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.