Knocking down error messages with named rvalue links

Consider the following:

struct my_type {};

my_type make_my_type() { return my_type{}; }

void func(my_type&& arg) {}

int main()
{
    my_type&& ref = make_my_type();

    func(ref);
}

Needless to say, this code does not compile. I understand what I need to use std::move()in the second function call, but for understanding, I want to consider the code as is.

Trying to compile the above, Clang 3.5 tells me:

Error: there is no corresponding function to call func function

Note: the candidate function is not viable: unknown conversion from 'my_type' to 'my_type & &' for the 1st argument void func (my_type &) {}

While g ++ 4.9 says something almost identical:

error: cannot bind 'my_type' lvalue to 'my_type & &'

note: initializing argument 1 'void func (my_type &)'

, ref, , lvalue, - my_type&&... ?

, , , ( ) :

  • rvalues ​​ rvalue , ref lvalue, arg. Clang g++ , , ref ( ) my_type, " ".

  • lvalue, ref my_type, , my_type&&. Clang g++ , , , ref.

  • main() ref my_type, , my_type&&. , , , . ,

    static_assert(std::is_same<decltype(ref), my_type&&>::value, "");
    

    .

  • , .

, , std::move() rref rvalue; , " ".

+4
1

:

my_type x = func_returning_my_type_byvalue();
my_type & y = func_returning_my_type_byvalue();
my_type && z = func_returning_my_type_byvalue();

- x (rvalue), / x ( x func_returning_my_type_byvalue, ).

, x lvalue - , . , , . lvalues ​​ .

- ( ), lvalue. , :

my_type & y = func_returning_my_type_byreference();
// `y` will never use constructors or destructors

, -, . - func arg . , :

void func( my_type && arg ) {
    my_type && save_arg = arg;
}

, , , arg . arg (, ) , save_arg, save_arg - , . , save_arg , ​​ lval, , func, - !

, std:move . func, , , , .

arg , my_type&, rvalue. - . , "rvalue".

, increment/decment. , . operator++(void) (pre) operator++(int) (post). int, , // . .

rvalue lvalue lvalue, ?

: .

lvalue - , , . , lvalue, , .

, , :

int a; // created first, destroyed last
int b; // created second, destroyed 2nd-last
int & c = b; // fine, `c` goes out of scope before `b` per above
int && d = std::move(a); // fine, `a` outlives `d`, same situation as `c`

rvalue, , lvalue, - lvalue , c d. std::move, - d - , , , rvalue / , .

, lvalue, , , , , , , , . .

rvalue, , . . / elision, , :

int a = 2, b = 3; // lvalues
int && temp = a + b; // temp is constructed in-place using the result of operator+(int,int)

func

lvalue - , , , lvalues, rvalue.

:

func( std::move( variable ) ); // case 1
func( my_type() + my_type() ); // case 2

func , ( ). 1, rvalue , , , func , "" .

, , 1 , arg , func , - , arg , func , func - arg my_type&, my_type&&.

0

All Articles