Rvalue on the left side

Why is this code compiling? I thought the rvalues ​​returned by ctor are not in memory and therefore cannot be used as lvalues.

#include <iostream> #include <vector> class Y { public : explicit Y(size_t num = 0) : m_resource {std::vector<int>(num)} { } std::vector<int> m_resource; }; int main(int argc, const char * argv[]) { Y(1) = Y(0); // WHAT?!? return 0; } 
+7
c ++ c ++ 11 rvalue lvalue-to-rvalue
source share
2 answers

The synthesized assignment operator is declared as one of them (if it can be synthesized and not declared as deleted) according to clause 12.8 [class.copy]:

  • Y& Y::operator=(Y const&)
  • Y& Y::operator=(Y&) ()

That is, as with any other member function that is not specifically declared with ref-qualifiers , it applies to rvalues.

If you want to prevent a temporary object on the left side of the task, you need to declare it accordingly:

 class Y { public : explicit Y(std::size_t num = 0); Y& operator= (Y const&) & = default; }; 

The standard uses the name ref-qualifier for & to = default . Relevant Offer N2439 . I do not know where there is a good description of ref-qualifiers. There is information on this issue .

+7
source share

Not sure where you got this special rule. If there are any, then this is a rule (from Scott Meyers): if it has a name, it is equal to lvalue.

In this case, you create a temporary object and pass it to the destination method / function. There is no problem with this. In fact, it may even make sense to do this, as in

 // Applies foo to a copy, not the original. (Y(1) = y).foo() 

True, Y(*) have no names here, and therefore they are rvalues.

+1
source share

All Articles