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));
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With