简体   繁体   English

std :: move Vs std :: forward

[英]std::move Vs std::forward

This seems to be most relavant question already asked. 这似乎是已经提出的最相关的问题。

Whats the difference between std::move and std::forward 什么是std :: move和std :: forward之间的区别

But each answer is different and applies and says slightly different things. 但每个答案都是不同的,并且适用并且说的略有不同。 So I am confused. 所以我很困惑。

I have the following situation. 我有以下情况。

  • Copy item into container 将项目复制到容器中
    The Copy item is C++03 so I understand that quite well. 复制项目是C ++ 03所以我很清楚。
  • Construct item into container 将项目构造到容器中
    The Construct item into container I believe uses perfect forwarding correctly to forward the arguments through two functions to the constructor of T in emplaceBackInternal() (Please say otherwise if I am wrong). 将构造项置于容器中我认为正确使用完美转发通过两个函数将参数转发给emplaceBackInternal()的T的构造函数(如果我错了,请另外说明)。
  • Move item into container 将项目移动到容器中
    My problem seems to be understanding the moving an item into the container. 我的问题似乎是理解将物品移入容器。

The Code: 代码:

template<typename T>
class Container
{
    std::size_t length;
    T*          buffer;

public:
    void push_back(T const& value)
    {
         resizeIfRequired();
         pushBackInternal(value);
    }
    template<typename... Args>
    void emplace_back(Args&&... args)
    {
         resizeIfRequired();
         emplaceBackInternal(std::forward<T>(arg)...);
    }
    void push_back(T&& value)
    {
         resizeIfRequired();
         // Is this forward correct or should it be move
         moveBackInternal(std::forward<T>(value));
    }
private:
    void pushBackInternal(T const& value)
    {
         // Copy construct object into buffer;
         new (buffer + length) T(value);
         ++length;
    }
    template<typename... Args)
    void emplaceBackInternal(Args&&... args)
    {
         // Construct object into buffer using arguments;
         new (buffer + length) T(std::forward<T>(args)...);
         ++length;
    }
    void moveBackInternal(T&& value)
    {
         // Move construct object into buffer;
         // Is this forward correct or should it be move
         new (buffer + length) T(std::forward<T>(value));
         ++length;
    }
};

I include all three here to compare the three functions with the answers provided in the previously mentioned answer. 我在这里包括所有三个,将三个函数与前面提到的答案中提供的答案进行比较。 The main reason is that move and construct looks so similar that it feels like they should be the same. 主要原因是moveconstruct看起来非常相似,感觉它们应该是相同的。

Answer @Potatoswatter Score 67 回答@Potatoswatter得分67

std::forward has a single use case: to cast a templated function parameter std :: forward有一个用例:转换模板化的函数参数

By this definition I should be using std::move inside push_back(T&& value) and moveBackInternal(T&& value) as the value is not a template parameter for the function. 根据这个定义,我应该使用std::move push_back(T&& value)moveBackInternal(T&& value)因为该值不是函数的模板参数。

Answer @Howard Hinnant Score 38 回答@Howard Hinnant得分38

If Y is an lvalue reference, the result will be an lvalue expression. 如果Y是左值引用,则结果将是左值表达式。 If Y is not an lvalue reference, the result will be an rvalue (xvalue to be precise) expression. 如果Y不是左值引用,则结果将是rvalue (精确的xvalue)表达式。

Seems by this definition I can use either std::move or std::forward . 看来这个定义我可以使用std::movestd::forward

Answer @Bo Persson Score 11 回答@Bo Persson得分11

std::forward is used to forward a parameter exactly the way it was passed to a function. std :: forward用于完全按照传递给函数的方式转发参数。

Seems to say that std::forward is acceptable (though if I follow the link in the answer all the examples use templated functions). 似乎说std::forward是可以接受的(尽管如果我按照答案中的链接所有示例都使用模板化函数)。

In this case: 在这种情况下:

void push_back(T&& value)
{
     resizeIfRequired();
     moveBackInternal(std::forward<T>(value));  // (1)             
     moveBackInternal(std::move(value));        // (2) 

}

std::forward<T>(value) and std::move(value) are identical in this scenario (it doesn't matter between (1) and (2) ... so use (2) ). std::forward<T>(value)std::move(value)在这种情况下是相同的 (在(1)(2)之间无关紧要...所以使用(2) )。

move is an unconditional cast to xvalue. move是对xvalue的无条件转换。 That line gives you an expression of type T&& that's an rvalue, always. 该行为您提供了一个类型为T&&的表达式,它始终是一个右值。

forward is a conditional cast. forward是一个有条件的演员。 If T is an lvalue reference type, it yields an lvalue. 如果T是左值引用类型,则产生左值。 Otherwise (if it's either not a reference type or an rvalue reference type), it yields an rvalue. 否则(如果它不是引用类型或右值引用类型),它会产生一个右值。 In our case, T is not a reference type - so we get an rvalue. 在我们的例子中, T不是引用类型 - 所以我们得到一个rvalue。

Either way, we end up at the same point - we call moveBackInternal with value cast as an rvalue. 无论哪种方式,我们最终都在同一点 - 我们调用moveBackInternal并将value为右值。 Just move() is a simpler way of getting there. 只需move()是一种更简单的方法。 forward<T> works , but it's unnecessary. forward<T> 有效 ,但没必要。

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

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