Should implicitly generated assignment operators be & ref-qualified?

后端 未结 2 1941
你的背包
你的背包 2020-12-03 11:32

The following code compiles without problem on gcc 4.8.1:

#include 

struct foo
{
};

int main()
{
    foo bar;

    foo() = bar;
    foo() =          


        
相关标签:
2条回答
  • 2020-12-03 12:18

    Well, there are certain legitimate use cases for assigning to an rvalue. To quote from Ref-qualifiers for assignment operators in the Standard Library:

    There are only a few very specific types for which it makes sense to support assigning to an rvalue. In particular, types that serve as a proxy, e.g., vector<bool>::reference, and types whose assignment operators are const-qualified (e.g., slice_array).

    The C++ standard committee obviously felt that default assignment should not have an implicit ref qualifier - rather it should be explicitly declared. Indeed, there may be existing code which would stop working if all of a sudden all implicitly declared assignment operators didn't work with rvalues.

    Granted, it's a bit hard to contrive an example where we want an implicitly declared assignment operator to work with rvalues, but the C++ standard committee likely doesn't want to take these kind of chances when it comes to preserving backwards compatibility. Code like this:

    int foo_counter = 0;
    
    struct Foo
    {
        Foo()
        {
            ++foo_counter;
        }
    
        ~Foo()
        {
            --foo_counter;
        }
    };
    
    int main()
    {
        Foo() = Foo();
    }
    

    ...wouldn't work anymore. And at the end of the day, the standards committee wants to make sure that previously valid C++ (no matter how stupid or contrived) continues to work in C++11.

    0 讨论(0)
  • 2020-12-03 12:22

    It seems like your question is more "Why would assignment to an rvalue ever be useful?" rather than "Why doesn't the standard ref-qualify auto generated constructors?"

    The reason assignment to an rvalue is allowed is because there are some cases where it is useful.

    One example usage is with std::tie (link):

    #include <set>
    #include <tuple>
    
    int main()
    {
        std::set<int> s;
    
        std::set<int>::iterator iter;
        bool inserted;
    
        // unpacks the return value of insert into iter and inserted
        std::tie(iter, inserted) = s.insert(7);
    }
    

    Example borrowed from cppreference.com then modified

    0 讨论(0)
提交回复
热议问题