Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass by value or rvalue-ref

For move enabled classes is there a difference between this two?

struct Foo {
typedef std::vector<std::string> Vectype;
Vectype m_vec;
//this or
void bar(Vectype&& vec)
{
   m_vec = std::move(vec);
}
//that
void bar(Vectype vec)
{
    m_vec = std::move(vec);
}
};
int main()
{
   Vectype myvec{"alpha","beta","gamma"};
   Foo fool; 
   fool.bar(std::move(myvec));
}

My understanding is that if you use a lvalue myvec you also required to introduce const Vectype& version of Foo::bar() since Vectype&& won't bind. That's aside, in the rvalue case, Foo::bar(Vectype) will construct the vector using the move constructor or better yet elide the copy all together seeing vec is an rvalue (would it?). So is there a compelling reason to not to prefer by value declaration instead of lvalue and rvalue overloads? (Consider I need to copy the vector to the member variable in any case.)

like image 466
hurcan solter Avatar asked Jun 27 '13 13:06

hurcan solter


People also ask

Is it faster to pass by reference or value?

As a rule of thumb, passing by reference or pointer is typically faster than passing by value, if the amount of data passed by value is larger than the size of a pointer.

Is pass by value more efficient than pass by reference?

Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.

What is the difference between L value and R value references?

“l-value” refers to a memory location that identifies an object. “r-value” refers to the data value that is stored at some address in memory. References in C++ are nothing but the alternative to the already existing variable. They are declared using the '&' before the name of the variable.

Why do we need rvalue reference?

Rvalue references is a small technical extension to the C++ language. Rvalue references allow programmers to avoid logically unnecessary copying and to provide perfect forwarding functions. They are primarily meant to aid in the design of higer performance and more robust libraries.


3 Answers

The pass-by-value version allows an lvalue argument and makes a copy of it. The rvalue-reference version can't be called with an lvalue argument.

Use const Type& when you don't need to change or copy the argument at all, use pass-by-value when you want a modifiable value but don't care how you get it, and use Type& and Type&& overloads when you want something slightly different to happen depending on the context.

like image 61
aschepler Avatar answered Sep 29 '22 04:09

aschepler


The pass-by-value function is sufficient (and equivalent), as long as the argument type has an efficient move constructor, which is true in this case for std::vector.

Otherwise, using the pass-by-value function may introduce an extra copy-construction compared to using the pass-by-rvalue-ref function.

See the answer https://stackoverflow.com/a/7587151/1190077 to the related question Do I need to overload methods accepting const lvalue reference for rvalue references explicitly? .

like image 27
Hugues Avatar answered Sep 29 '22 04:09

Hugues


Yes, the first one (Vectype&& vec) won't accept a const object or simply lvalue.

If you want to save the object inside like you do, it's best to copy(or move if you pass an rvalue) in the interface and then move, just like you did in your second example.

like image 40
Bartek Banachewicz Avatar answered Sep 29 '22 03:09

Bartek Banachewicz