I would like to propose that we allow move-only constructors for our classes. They look like this:
class Foo {
Foo(Foo&& other) { ... }
}
Here Foo can only be constructed from another Foo that is an rvalue (ie it doesn't have a name of its own in the code).
I'd like to propose this specifically because I believe that nullptr support in scoped_ptr is not possible without it. That points to this being a very useful construct.
-- More below the fold --
Here's gritty details about why scoped_ptr + nullptr can't happen without a move-only constructor (I think):
scoped_ptr<int> Function() {
return nullptr;
}
scoped_ptr<int> var = Function();
This function requires a constructor that turns the nullptr into a scoped_ptr<int> to compile. But then when we try to construct var, it tries to use the private copy constructor, which does not work.
scoped_ptr<int> Function2() {
return scoped_ptr<>;
}
I believe Function2 works because you have an explicit scoped_ptr, which we return. Then when we create var, it will do an implicit conversion from scoped_ptr<> to RValue, and scoped_ptr has a constructor from RValue.
But if we use that implicit conversion inside Function to go from nullptr to scoped_ptr<>, we're unable to produce an RValue in order to make var. So this is not possible without 2 implicit conversions, or using a move constructor on scoped_ptr.
Any solution without a move constructor needs to create an explicit scoped_ptr<> inside Function() to return, which means you're just making sugar for scoped_ptr<>(), and really this has nothing to do with nullptr anymore.