Using the return value of operator* from a "dead" unique_ptr is bad.
The following code compiles but results of course in Undefined Behavior:
auto& ref = *std::make_unique<int>(7);
std::cout << ref << std::endl;
Why didn't the standard make the return type of operator* for an rvalue of std::unique_ptr an rvalue of the internal value, instead of an lvalue, like this:
// could have been done inside unique_ptr
T& operator*() & { return *ptr; }
T&& operator*() && { return std::move(*ptr); }
In which case this would work fine:
std::cout << *std::make_unique<int>(7) << std::endl;
But the code at the beginning would not compile (cannot bind an rvalue to an lvalue).
Side note: of course someone could still write bad code like the below, but it is saying "I'm UB" more verbosely, IMHO, thus less relevant for this discussion:
auto&& ref = *std::make_unique<int>(7);
std::cout << ref << std::endl;
operator*
. Why wasn't the ref qualified version added? Perhaps an oversight, maybe a good idea for a paper. – AndyGT&& operator*() && { return ::std::move(*ptr); }
, otherwise it wouldn't even compile – Angew is no longer proud of SOauto ptr = std::make_unique<int>(7); auto& ref = *ptr;
still work? – Some programmer dudeauto&&
doesn't mean "I'm UB". – Nicol Bolas