Re: Implicit move constructor rules in c++0x still badly broken?
Howard Hinnant wrote:
Here's Dave's code, completed and instrumented:
#include <iostream>
class Y
{
int state_;
public:
enum {destructed = -2, moved_from, default_constructed};
Y() : state_(default_constructed) {}
Y(const Y& a) : state_(a.state_) {}
Y& operator=(const Y& a) {state_ = a.state_; return *this;}
Y(Y&& a) : state_(a.state_)
{
std::cout << "Moving out!\n";
a.state_ = moved_from;
}
Y& operator=(Y&& a)
{
state_ = a.state_;
a.state_ = moved_from;
return *this;
}
~Y()
{
state_ = destructed;
}
explicit Y(int s) : state_(s) {}
friend
std::ostream&
operator<<(std::ostream& os, const Y& a)
{
switch (a.state_)
{
case Y::destructed:
os << "Y is destructed\n";
break;
case Y::moved_from:
os << "Y is moved from\n";
break;
case Y::default_constructed:
os << "Y is default constructed\n";
break;
default:
os << "Y = " << a.state_ << '\n';
break;
}
return os;
}
friend bool operator==(const Y& x, const Y& y)
{return x.state_ == y.state_;}
friend bool operator<(const Y& x, const Y& y)
{return x.state_ < y.state_;}
};
class InvariantChecker
{
Y* v_;
InvariantChecker(const InvariantChecker&);
InvariantChecker& operator=(const InvariantChecker&);
public:
explicit InvariantChecker() : v_(0) {}
explicit InvariantChecker(Y& v) : v_(&v) {}
~InvariantChecker()
{
if (v_)
std::cout << *v_ << '\n';
}
};
Y
f(bool choose)
{
Y a(1), b(2);
InvariantChecker xa(a), xb(b);
// Incorrect comment follows:
// The use of ?: guarantees that there will be no copy elision.
// Instead, either a or b will be *moved* into the return value.
return choose ? a : b;
// xb and xa get destroyed here
// b and a get destroyed thereafter
}
int main()
{
Y y = f(true);
}
Using a recent build of clang and libc++ this, at least for me
outputs:
Y = 2
Y = 1
Using g++-4.4 with libc++ I get the identical output. To demonstrate
Dave's point I expect to see:
Y is moved from
in the output.
Using the -fno-elide-constructors flag in clang or gcc shows that the
move occurs after the InvariantChecker destructors.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]