Could you tell me what is going on here? And why it is possible?
std::make_unique(1) = std::make_unique(1);
I thought
I thought that return of make_unique is r-value...
It is. But for class types like std::unique_ptr<...>
, the assignment is a call to an overloaded member function. You can pass rvalues as arguments to functions. And more specifically, call member functions on rvalues.
As an example, when you examine std::bitset
, you see that its reference
type is in fact a class type. The assignment operator for that type is overloaded. It accepts a bool
, but in fact performs a bit-wise operation to manipulate a flag in the packed memory of the bitset
.
It works for unique_ptr
rvalues because it's overloaded (and is implicitly generated for other class types) without any ref-qualifiers. I.e.
unique_ptr& operator=( unique_ptr&& r ) noexcept;
... and not...
unique_ptr& operator=( unique_ptr&& r ) & noexcept;
// Can only be used on lvalues, no overload for rvalues
Which would have been for very little gain. And it's unlikely that the implicitly generated one would ever be for lvalues only. A lot of code (some that even predates C++11) uses assignment on rvalues, without ref-qualifying the operators. So that would break existing code bases.