Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 556691
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T11:56:48+00:00 2026-05-13T11:56:48+00:00

C++ compilers automatically generate copy constructors and copy-assignment operators. Why not swap too? These

  • 0

C++ compilers automatically generate copy constructors and copy-assignment operators. Why not swap too?

These days the preferred method for implementing the copy-assignment operator is the copy-and-swap idiom:

T& operator=(const T& other)
{
    T copy(other);
    swap(copy);
    return *this;
}

(ignoring the copy-elision-friendly form that uses pass-by-value).

This idiom has the advantage of being transactional in the face of exceptions (assuming that the swap implementation does not throw). In contrast, the default compiler-generated copy-assignment operator recursively does copy-assignment on all base classes and data members, and that doesn’t have the same exception-safety guarantees.

Meanwhile, implementing swap methods manually is tedious and error-prone:

  1. To ensure that swap does not throw, it must be implemented for all non-POD members in the class and in base classes, in their non-POD members, etc.
  2. If a maintainer adds a new data member to a class, the maintainer must remember to modify that class’s swap method. Failing to do so can introduce subtle bugs. Also, since swap is an ordinary method, compilers (at least none I know of) don’t emit warnings if the swap implementation is incomplete.

Wouldn’t it be better if the compiler generated swap methods automatically? Then the implicit copy-assignment implementation could leverage it.

The obvious answer probably is: the copy-and-swap idiom didn’t exist when C++ was developed, and doing this now might break existing code.

Still, maybe people could opt-in to letting the compiler generate swap using the same syntax that C++0x uses for controlling other implicit functions:

void swap() = default;

and then there could be rules:

  1. If there is a compiler-generated swap method, an implicit copy-assignment operator can be implemented using copy-and-swap.
  2. If there is no compiler-generated swap method, an implicit copy-assignment operator would be implemented as before (invoking copy-assigment on all base classes and on all members).

Does anyone know if such (crazy?) things have been suggested to the C++ standards committee, and if so, what opinions committee members had?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T11:56:48+00:00Added an answer on May 13, 2026 at 11:56 am

    This is in addition to Terry’s answer.

    The reason we had to make swap functions in C++ prior to 0x is because the general free-function std::swap was less efficient (and less versatile) than it could be. It made a copy of a parameter, then had two re-assignments, then released the essentially wasted copy. Making a copy of a heavy-weight class is a waste of time, when we as programmers know all we really need to do is swap the internal pointers and whatnot.

    However, rvalue-references relieve this completely. In C++0x, swap is implemented as:

    template <typename T>
    void swap(T& x, T& y)
    {
        T temp(std::move(x));
        x = std::move(y);
        y = std::move(temp);
    }
    

    This makes much more sense. Instead of copying data around, we are merely moving data around. This even allows non-copyable types, like streams, to be swapped. The draft of the C++0x standard states that in order for types to be swapped with std::swap, they must be rvalue constructable, and rvalue assignable (obviously).

    This version of swap will essentially do what any custom written swap function would do. Consider a class we’d normally write swap for (such as this “dumb” vector):

    struct dumb_vector
    {
        int* pi; // lots of allocated ints
    
        // constructors, copy-constructors, move-constructors
        // copy-assignment, move-assignment
    };
    

    Previously, swap would make a redundant copy of all our data, before discarding it later. Our custom swap function would just swap the pointer, but can be clumsy to use in some cases. In C++0x, moving achieves the same end result. Calling std::swap would generate:

    dumb_vector temp(std::move(x));
    x = std::move(y);
    y = std::move(temp);
    

    Which translates to:

    dumb_vector temp;
    temp.pi = x.pi; x.pi = 0; // temp(std::move(x));
    x.pi = y.pi; y.pi = 0; // x = std::move(y);
    y.pi = temp.pi; temp.pi = 0; // y = std::move(temp);
    

    The compiler will of course get rid of redundant assignment’s, leaving:

    int* temp = x.pi;
    x.pi = y.pi;
    y.pi = temp;
    

    Which is exactly what our custom swap would have made in the first place. So while prior to C++0x I would agree with your suggestion, custom swap‘s aren’t really necessary anymore, with the introduction of rvalue-references. std::swap will work perfectly in any class that implements move functions.

    In fact, I’d argue implementing a swap function should become bad practice. Any class that would need a swap function would also need rvalue functions. But in that case, there is simply no need for the clutter of a custom swap. Code size does increase (two ravlue functions versus one swap), but rvalue-references don’t just apply for swapping, leaving us with a positive trade off. (Overall faster code, cleaner interface, slightly more code, no more swap ADL hassle.)

    As for whether or not we can default rvalue functions, I don’t know. I’ll look it up later or maybe someone else can chime in, but that would sure be helpful. 🙂

    Even so, it makes sense to allow default rvalue functions instead of swap. So in essence, as long as they allow = default rvalue functions, your request has already been made. 🙂

    EDIT: I did a bit of searching, and the proposal for = default move was proposal n2583. According to this (which I don’t know how to read very well), it was “moved back.” It is listed under the section titled “Not ready for C++0x, but open to resubmit in future “. So looks like it won’t be part of C++0x, but may be added later.

    Somewhat disappointing. 🙁

    EDIT 2: Looking around a bit more, I found this: Defining Move Special Member Functions which is much more recent, and does look like we can default move. Yay!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 384k
  • Answers 384k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer Update: As of SQL Server 2016 parsing JSON in TSQL… May 14, 2026 at 11:06 pm
  • Editorial Team
    Editorial Team added an answer Basically trapped the error that i receive when creating the… May 14, 2026 at 11:06 pm
  • Editorial Team
    Editorial Team added an answer I found the answer: I needed the requirePermission="false" tag in… May 14, 2026 at 11:06 pm

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.