我有一个操作矢量的代码:
template<typename T>
void doVector(vector<T>& v, T&& value) {
//....
v.push_back(value);
//...
}
Run Code Online (Sandbox Code Playgroud)
正常情况下push_back,我需要使用forward(value),move(value)还是仅仅value(根据新的C++ 11)?它们如何影响性能?
例如,
v.push_back(forward<T>(value));
Run Code Online (Sandbox Code Playgroud)
Naw*_*waz 17
当第二个参数是当前的代码不能编译左值,因为T&&会变成是X&,这意味着T需要为X&这反过来又意味着std::vector<T>将成为std::vector<X&>其将不匹配这是第一个参数std::vector<X> &.因此,这是一个错误.
我会使用两个模板参数:
template<typename T, typename V>
void doVector(vector<T> & v, V && value)
{
v.emplace_back(std::forward<V>(value));
}
Run Code Online (Sandbox Code Playgroud)
由于V可以从不同的类型T,所以emplace_back使得更多的意义,因为它不仅解决了这个问题,它使代码更通用.:-)
现在是下一个改进:因为我们正在使用从参数emplace_back创建类型的对象(可能使用构造函数),我们可以利用这个事实,并使其具有可变函数:Tvalue
template<typename T, typename ...V>
void doVector(vector<T> & v, V && ... value)
{
v.emplace_back(std::forward<V>(value)...);
}
Run Code Online (Sandbox Code Playgroud)
这更加通用,因为您可以将其用作:
struct point
{
point(int, int) {}
};
std::vector<point> pts;
doVector(pts, 1, 2);
std::vector<int> ints;
doVector(ints, 10);
Run Code Online (Sandbox Code Playgroud)
希望有所帮助.
forward(value) 如果你需要完美的转发意义,保留像l值,r值这样的东西.
转发非常有用,因为它可以帮助您避免为具有l-val,r-val和引用参数的不同组合的函数编写多个重载
move(value) 实际上是一种将l值转换为r值的转换运算符
在性能方面,都避免制作额外的物品副本,这是主要的好处.
所以他们真的做了两件事
当你说普通的push_back时,我不确定你的意思,这里有两个签名.
void push_back( const T& value );
void push_back( T&& value );
Run Code Online (Sandbox Code Playgroud)
第一个你可以通过任何正常的l-val,但是对于第二个你必须"移动"一个l-val或向前一个r-val.请记住,一旦移动l-val就无法使用它
这里的奖励是一种资源,似乎可以很好地解释r-val-refs的概念以及与之相关的其他概念.
正如其他人所建议你也可以切换到使用emplace,因为它实际上完美地将参数转发给对象的构造函数,这意味着你可以随意传递它.
std::forward.std::move.例如
template <typename T>
void funcA(T&& t) {
funcC(std::forward<T>(t)); // T is deduced and therefore T&& means forward-ref.
}
void funcB(Foo&& f) {
funcC(std::move(f)); // f is r-value, use move.
}
Run Code Online (Sandbox Code Playgroud)
以下是Scott Meyers的优秀视频,解释转发参考(他称之为通用参考)以及何时使用完美转发和/或std::move:
C++和2012年之后:Scott Meyers - C++中的通用引用11
有关使用的更多信息,请参阅此相关问题std::forward:使用forward的优点
| 归档时间: |
|
| 查看次数: |
1630 次 |
| 最近记录: |