Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I use forward and move?

Tags:

c++

c++11

I have a code that operates on a vector:

template<typename T>
void doVector(vector<T>& v, T&& value) {
    //....
    v.push_back(value);
    //...
}

For normal push_back, do I need to use forward(value), move(value) or just value (according to new C++11) ? and how do they impact the performance?

For example,

v.push_back(forward<T>(value));
like image 605
SwiftMango Avatar asked Aug 13 '13 16:08

SwiftMango


1 Answers

The current code will not compile when the second argument is lvalue because T&& will turn out to be X& which means T needs to be X& which in turn means std::vector<T> will become std::vector<X&> which will NOT match the first argument which is std::vector<X> &. Hence, it is an error.

I would use two template parameters:

template<typename T, typename V>
void doVector(vector<T> & v, V && value) 
{
    v.emplace_back(std::forward<V>(value));
}

Since V could a different type from T, so emplace_back makes more sense, because not only it solves the problem, it makes the code more generic. :-)

Now the next improvement : since we're using emplace_back which creates the object of type T from argument value (possibly using constructor), we could take advantage of this fact, and make it variadic function:

template<typename T, typename ...V>
void doVector(vector<T> & v, V && ... value) 
{
    v.emplace_back(std::forward<V>(value)...);
}

That is even more generic, as you could use it as:

struct point
{
    point(int, int) {}
};

std::vector<point> pts;
doVector(pts, 1, 2);

std::vector<int> ints;
doVector(ints, 10);

Hope that helps.

like image 106
Nawaz Avatar answered Oct 19 '22 01:10

Nawaz