In N2812 is an example in the Introduction where a unique_ptr is given as a value parameter
void push_back2(
std::list<std::unique_ptr<int>>& l, std::unique_ptr<int> a)
{
l.push_back(a); // oops: moves from the lvalue 'a', silently!
l.push_back(a); // oops: 'a' no longer has its original value
}
The paper discusses a problem with RValue/LValue overload resolution, but thats not my point.
I wonder, if providing the argument std::unique_ptr<int> a by-value is not causing a compiler error? It would copy it, right? And that is not allowed for unique_ptr
I am aware that the paper is quite old, maybe the definition of unique_ptr has changed, since. But maybe it’s just a typo and the author wanted to write std::unique_ptr<int> &a instead?
My gcc 4.7.0 agrees with me, but thats no proof 🙂
void push_back2( std::list<std::unique_ptr<int>>&, std::unique_ptr<int> ) { };
int main() {
list<unique_ptr<int>> lst;
unique_ptr<int> num { new int{4} };
push_back2(lst, num); //ERR: use of deleted function
}
Your knowledge and assumptions about the behavior are correct.
The paper’s example is confusing as it is conflating two languages: C++ with concepts and C++ without concepts. In the paper’s pretend language, the
listpush_back which requiresCopyConstructibleis SFINAE’d away, leaving only the overload requiringMoveConstructible. In such alistdesign, and with the old rules that an lvalue could bind to an rvalue-reference, then thepush_backwould have implicitly moved fromatwice.Note that we were in no danger at any time of
listactually behaving this way. The authors were simply trying to set up a situation whereconst value_type&andvalue_type&&were not overloaded, and you had onlyvalue_type&&in the overload set.