Return std::move by value or by rvalue-ref?

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
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.