I think the answer is : implementing such a behavior yourself is pretty much trivial and hence the Standard didn't feel any need to impose any rule on the compiler itself. The C++ language is huge and not everything can be imagined before its use. Take for example, C++'s template. It was not first designed to be used the way it is used today (i.e it's metaprogramming capability). So I think, the Standard just gives the freedom, and didn't make any specific rule for std::move(other.p)
, following one of it's the design-principle: "You don't pay for what you don't use".
Although, std::unique_ptr
is movable, though not copyable. So if you want pointer-semantic which is movable and copyable both, then here is one trivial implementation:
template<typename T>
struct movable_ptr
{
T *pointer;
movable_ptr(T *ptr=0) : pointer(ptr) {}
movable_ptr<T>& operator=(T *ptr) { pointer = ptr; return *this; }
movable_ptr(movable_ptr<T> && other)
{
pointer = other.pointer;
other.pointer = 0;
}
movable_ptr<T>& operator=(movable_ptr<T> && other)
{
pointer = other.pointer;
other.pointer = 0;
return *this;
}
T* operator->() const { return pointer; }
T& operator*() const { return *pointer; }
movable_ptr(movable_ptr<T> const & other) = default;
movable_ptr<T> & operator=(movable_ptr<T> const & other) = default;
};
Now you can write classes, without writing your own move-semantics:
struct T
{
movable_ptr<A> aptr;
movable_ptr<B> bptr;
//...
//and now you could simply say
T(T&&) = default;
T& operator=(T&&) = default;
};
Note that you still have to write copy-semantics and the destructor, as movable_ptr
is not smart pointer.
delete p
:) – Shogunatedelete p
-- how does the compiler know? If you require the pointer to be set to null, set it to null, don't have the compiler do it for classes that don't need it. – Incunabuladelete p
, so what is the point you're trying to make? – Incunabuladelete p
is a bad argument, raw pointers should never be owning. – DepredateT& operator=(T&&) = default;
and with my "proposal", it would do the right thing. – Shogunateunique_ptr
– Landholderstd::swap
on two pointers is an excellent example of where you don't wantstd::move
to auto-NULL pointers. And what is the "null" state for integers? True, an optimizer could solve the std::swap case to be ideal again, but I think such cases show that we better leave it alone. – Undenominationalstd::swap
issue? I'm not sure what you're getting at. Inefficiency due to unnecessary nulling out? – ShogunateNote: By "moving", I do not just mean the subexpression std::move(other.p)
This is whystd::move
is a @!#^ing ridiculous name for that construct. – Bibliogonymove(x)
means "you can treatx
as an rvalue". Maybe it would have been better ifmove()
had been calledrval()
, but by nowmove()
has been used for years." – Shogunateget_rvalue()
. Instead it's a "user-friendly" name, chosen because of its alleged most common use case, but since that only holds in conjunction with other language features (i.e. actually moving), I think it betrays the whole principle of C++. I'd accept the reasoning that it's too late to change (and by "it's" I mean during the late stages of C++11's standardisation, when I became aware of this calamity). – Bibliogonydelete
on any pointer members in the automatically generated destructor, I could simply say~T() = default;
and it would do the right thing, wouldn't it? But well... ;) – Diellarval
would be incorrect, becauserval(function)
yields an lvalue. – Undenominational