Re: C++0x: unique_ptr and std::move
On 28 Jan., 10:35, Micha=B3 'Khorne' Rzechonek <khor...@gmail.com>
wrote:
Hello,
I wanted o understand how rvalue references work, so I took GCC 4.3
with -std=c++0x flag and wrote code below.
[rearranged]
#include <iostream>
#include <cassert>
Don't you need <utility> as well for std::move?
using std::cout;
using std::endl;
using std::move;
template<typename T>
class unique_ptr {
public:
explicit unique_ptr(T *&&a_ptr): m_ptr(a_ptr) {
a_ptr = NULL;
}
That's unusual. But ok considering current rules. However, the
semantics of "&&" may change, see:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/
I would use
explicit unique_ptr(T * a_ptr): m_ptr(a_ptr) {}
instead.
unique_ptr(unique_ptr &&p): m_ptr(p.release()) {
cout << "Move" << endl;
}
T *release() {
T *ptr = m_ptr;
m_ptr = NULL;
return ptr;
}
T *get() {
return m_ptr;
}
T *operator->() {
return m_ptr;
}
The above two functions (get, operator->) should be const. Is there no
overload for operator* ?
~unique_ptr() {
if(m_ptr != NULL) {
delete m_ptr;
}
}
You don't need to check for null pointers here.
private:
unique_ptr(const unique_ptr &);
void operator=(const unique_ptr &);
void operator=(unique_ptr &&p);
You don't need an extra && overload here for operator=.
T *m_ptr;
};
struct Foo
{
[snip]
};
unique_ptr<Foo> source(int a = 0) {
return move(unique_ptr<Foo>(new Foo(a)));
}
void sink(unique_ptr<Foo> a_foo) {
cout << a_foo->a << endl;
}
int main() {
unique_ptr<Foo> foo( source(1) );
unique_ptr<Foo> bar = move(foo);
assert(foo.get() == NULL); // ok
unique_ptr<Foo> qux( source(2) );
sink( move(qux) );
assert(qux.get() == NULL); // ??
}
[rearranged]
What I don't understand is why 2nd assertion fails and move ctor is
not called. Please enlighten me :)
It fails? That's odd. I can't test it myself right now, unfortunately.
I guess it's either a compiler bug or we overlooked something.
Side question: does source() function look all right?
Yes. You don't need the extra move(), though. You only need move() if
you want to return a function's parameter or some other lvalue
reference as rvalue. Local variables (not including call-by-value
parameters) are automatically treated as rvalues in a return
statement.
Cheers!
SG