繁体   English   中英

什么时候应该使用前进和移动?

[英]When should I use forward and move?

我有一个操作矢量的代码:

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

对于普通的push_back ,我是否需要使用forward(value)move(value)或者只是value (根据新的C ++ 11)? 它们如何影响性能?

例如,

v.push_back(forward<T>(value));

当第二个参数是左值时,当前代码将无法编译,因为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));
}

由于V可以是与T不同的类型,因此emplace_back 更有意义,因为它不仅解决了问题,而且使代码更通用。 :-)

现在是下一个改进:因为我们正在使用emplace_back从参数value创建类型T的对象(可能使用构造函数),我们可以利用这个事实,并使其成为可变函数:

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

这更加通用,因为您可以将其用作:

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

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

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

希望有所帮助。

  1. 如果您需要完美的转发含义,则使用forward(value) ,保留l值,r值等内容。

  2. 转发非常有用,因为它可以帮助您避免为具有l-val,r-val和引用参数的不同组合的函数编写多个重载

  3. move(value)实际上是一种将l值转换为r值的转换运算符

  4. 在性能方面,都避免制作额外的物品副本,这是主要的好处。

所以他们真的做了两件事


当你说普通的push_back时,我不确定你的意思,这里有两个签名。

void push_back( const T& value );
void push_back( T&& value );

第一个你可以通过任何正常的l-val,但是对于第二个你必须“移动”一个l-val或向前一个r-val。 请记住,一旦移动l-val就无法使用它

这里的奖励是一种资源 ,似乎可以很好地解释r-val-refs的概念以及与之相关的其他概念。

正如其他人所建议你也可以切换到使用emplace,因为它实际上完美地将参数转发给对象的构造函数,这意味着你可以随意传递它。

  • 传递作为转发引用的参数时,请始终使用std::forward
  • 传递一个r值的参数时,请使用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.
}

以下是Scott Meyers的一段精彩视频,解释了转发引用(他称之为通用引用 )以及何时使用完美转发和/或std::move

C ++和2012年之后:Scott Meyers - C ++中的通用引用11

有关使用std::forward更多信息,请参阅此相关问题: 使用forward的优点

http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Scott-Meyers-Universal-References-in-Cpp11

那个视频,IMO,有关何时使用std :: forward以及何时使用std :: move的最佳解释。 它提出了通用参考的概念,这是IMO一个非常有用的推理移动语义的工具。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM