Return std::move by value or by rvalue-ref?
Aug 23, 2014 at 4:11am UTC
http://coliru.stacked-crooked.com/a/7ef314661039dbf3 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
struct Test
{
Type t;
auto stealA()
-> Type
{
return std::move(t);
}
auto stealB()
-> Type &&
{
return std::move(t);
}
};
int main()
{
Test t1 {{"A" }};
auto a = t1.stealA();
std::cout << a.s << std::endl;
Test t2 {{"B" }};
auto b = t2.stealB();
std::cout << b.s << std::endl;
}
string ctor "A"
move ctor "A"
A
string ctor "B"
move ctor "B"
B
I have read
http://stackoverflow.com/a/1116763/1959975 but that still leaves me wondering, should I prefer stealA, stealB, or something else?
Last edited on Aug 23, 2014 at 4:12am UTC
Aug 23, 2014 at 5:45am UTC
Must be stolen (forced): use prvalue.
Can be stolen (caller has a choice) : use xvalue.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#include <cstdio>
#include <utility>
#include <iostream>
struct base
{
base() = default ;
base( base&& ) noexcept { std::puts( "base::move_constructor" ) ; }
virtual ~base() = default ;
virtual const char * id() const { return "base" ; }
};
struct derived : base
{
derived() = default ;
derived( derived&& ) noexcept { std::puts( "derived::move_constructor" ) ; }
virtual const char * id() const override { return "derived" ; }
};
struct A
{
derived d ;
// prvalue: not polymorphic
base foo_prvalue_base() { return std::move(d) ; } // sliced and move constructed prvalue
derived foo_prvalue_derived() { return std::move(d) ; } // move constructed prvalue
// xvalue: polymorphic
base&& bar_xvalue() { return std::move(d) ; } // xvalue
};
int main()
{
A a ;
// moved, not polymorphic
std::cout << "1.\n" ;
std::cout << a.foo_prvalue_base().id() << '\n' ;
// moved, not polymorphic
std::cout << "\n2.\n" ;
std::cout << a.foo_prvalue_derived().id() << '\n' ;
// moveable xvalue, polymorphic, but not moved
std::cout << "\n3.\n" ;
std::cout << a.bar_xvalue().id() << '\n' ;
// moveable xvalue, polymorphic, sliced and moved
std::cout << "\n4.\n" ;
auto x = a.bar_xvalue() ;
// moveable xvalue, polymorphic, type restored and moved
std::cout << "\n5.\n" ;
auto y = dynamic_cast <derived&&>( a.bar_xvalue() ) ;
}
http://coliru.stacked-crooked.com/a/975773b4d3756862
Topic archived. No new replies allowed.