@MarcoFalke Yes, but they also don’t have a universal reference constructor like we do.
The problem is that return values are passed through a move constructor if they exist, before copy constructors. See here under “Automatic move from local variables and parameters”.
Because the default move constructor is removed by adding the default constructor/assignment operator, our return values are passed through our universal constructor as rvalues. That’s really not a problem except that we want to minimize what’s going through that constructor so that we can apply the lifetimebound attribute to it.
( Bonus TIL: apparently c++17 does away with this return value path altogether when possible: “If expression is a prvalue, the result object is initialized directly by that expression. This does not involve a copy or move constructor when the types match” )
So there are 2 possible solutions for us (if you’re willing to accept that there’s something to be solved)
- remove the default ctor/assignment operator as I’ve done here, thus enabling a trivial move constructor for return values to pass through
- remove our universal reference constructor and replace it with something less greedy
Your question made me look up the current c++20 draft spec, where I noticed that the universal reference constructor has been removed in a newish revision. So what’s on cppreference is actually stale.
But that gives us an easy answer to the question above, we should just update our implementation to match the latest draft spec. I’m going to close this and open a new PR with that approach, since it’s sufficiently different from what’s here.