I'm not sure what's going on here, but with a recent 4.5 snapshot this program fails:
#include <utility> #include <cassert> template<typename T> struct S { S() : buf() { } void set(T&& i) { buf = std::move(i); } T&& get() { return std::move(buf); } private: T buf; }; struct pod { }; template class S<int>; template class S<double>; template class S<pod>; int main() { S<int> s; s.set(5); assert( s.get() == 5 ); } Compiling with 4.5.0 20090528 gives these warnings: tmpret.cc: In member function T&& S<T>::get() [with T = int]: tmpret.cc:19: instantiated from here tmpret.cc:11: warning: returning reference to temporary tmpret.cc: In member function T&& S<T>::get() [with T = double]: tmpret.cc:20: instantiated from here tmpret.cc:11: warning: returning reference to temporary tmpret.cc: In function int main(): tmpret.cc:27: warning: <anonymous> is used uninitialized in this function And the assertion fails at runtime. Notice that the explicit instantiations of S<int> and S<double> trigger the warning about returning a reference to a temporary for this line: T&& get() { return std::move(buf); } but the S<pod> instantiation doesn't. I can't see what's wrong with that line, it seems that std::move creates a temporary when 'T' is a builtin type. It looks as though std::move(buf) instantiates std::move<T>(T&&) with T = int&, so the rvalue-reference binds to an int& not an int. Am I missing something or is this a bug in either std::move or g++? N.B. the changes to std::move proposed by n2844 are not in the WP yet, so the specification of std::move may change. -- Summary: [C++0x] std::move and builtin types Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jwakely dot gcc at gmail dot com GCC build triplet: x86_64-unknown-linux-gnu GCC host triplet: x86_64-unknown-linux-gnu GCC target triplet: x86_64-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40295