std::move 比 std::forward
std::move Vs std::forward
这似乎是已经问过的最相关的问题。
Whats the difference between std::move and std::forward
但每个答案都不同,适用的内容也略有不同。所以我很困惑。
我有以下情况。
- 将项目复制到容器中
Copy 项是 C++03,所以我非常理解。
- 将项目构建到容器中
Construct item into container 我相信使用完美转发正确地通过两个函数将参数转发给 emplaceBackInternal()
中 T 的构造函数(如果我错了请另行说明)。
- 将项目移入容器
我的问题似乎是理解如何将一个项目移入容器。
代码:
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;
}
};
我把这三个都包括在这里是为了将这三个函数与前面提到的答案中提供的答案进行比较。主要是move
和construct
长得很像,感觉应该是一样的
Answer @Potatoswatter Score 67
std::forward has a single use case: to cast a templated function parameter
根据这个定义,我应该在 push_back(T&& value)
中使用 std::move
并且
moveBackInternal(T&& value)
因为值不是函数的模板参数。
Answer @Howard Hinnant Score 38
If Y is an lvalue reference, the result will be an lvalue expression. If Y is not an lvalue reference, the result will be an rvalue (xvalue to be precise) expression.
根据这个定义,我似乎可以使用 std::move
或 std::forward
。
Answer @Bo Persson Score 11
std::forward is used to forward a parameter exactly the way it was passed to a function.
似乎说 std::forward
是可以接受的(尽管如果我在答案中遵循 link,所有示例都使用模板函数)。
在这种情况下:
void push_back(T&& value)
{
resizeIfRequired();
moveBackInternal(std::forward<T>(value)); // (1)
moveBackInternal(std::move(value)); // (2)
}
std::forward<T>(value)
和 std::move(value)
在这种情况下 相同 ((1)
和 (2)
之间没有关系。 .. 所以使用 (2)
)。
move
是对 xvalue 的无条件转换。该行给你一个 T&&
类型的表达式,它总是一个右值。
forward
是条件转换。如果 T
是左值引用类型,它会产生一个左值。否则(如果它不是引用类型或右值引用类型),它会产生一个右值。在我们的例子中,T
不是引用类型 - 所以我们得到一个右值。
无论哪种方式,我们都在同一点结束 - 我们调用 moveBackInternal
并将 value
转换为右值。 move()
是一种更简单的方法。 forward<T>
有效,但没有必要。
这似乎是已经问过的最相关的问题。
Whats the difference between std::move and std::forward
但每个答案都不同,适用的内容也略有不同。所以我很困惑。
我有以下情况。
- 将项目复制到容器中
Copy 项是 C++03,所以我非常理解。 - 将项目构建到容器中
Construct item into container 我相信使用完美转发正确地通过两个函数将参数转发给emplaceBackInternal()
中 T 的构造函数(如果我错了请另行说明)。 - 将项目移入容器
我的问题似乎是理解如何将一个项目移入容器。
代码:
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;
}
};
我把这三个都包括在这里是为了将这三个函数与前面提到的答案中提供的答案进行比较。主要是move
和construct
长得很像,感觉应该是一样的
Answer @Potatoswatter Score 67
std::forward has a single use case: to cast a templated function parameter
根据这个定义,我应该在 push_back(T&& value)
中使用 std::move
并且
moveBackInternal(T&& value)
因为值不是函数的模板参数。
Answer @Howard Hinnant Score 38
If Y is an lvalue reference, the result will be an lvalue expression. If Y is not an lvalue reference, the result will be an rvalue (xvalue to be precise) expression.
根据这个定义,我似乎可以使用 std::move
或 std::forward
。
Answer @Bo Persson Score 11
std::forward is used to forward a parameter exactly the way it was passed to a function.
似乎说 std::forward
是可以接受的(尽管如果我在答案中遵循 link,所有示例都使用模板函数)。
在这种情况下:
void push_back(T&& value)
{
resizeIfRequired();
moveBackInternal(std::forward<T>(value)); // (1)
moveBackInternal(std::move(value)); // (2)
}
std::forward<T>(value)
和 std::move(value)
在这种情况下 相同 ((1)
和 (2)
之间没有关系。 .. 所以使用 (2)
)。
move
是对 xvalue 的无条件转换。该行给你一个 T&&
类型的表达式,它总是一个右值。
forward
是条件转换。如果 T
是左值引用类型,它会产生一个左值。否则(如果它不是引用类型或右值引用类型),它会产生一个右值。在我们的例子中,T
不是引用类型 - 所以我们得到一个右值。
无论哪种方式,我们都在同一点结束 - 我们调用 moveBackInternal
并将 value
转换为右值。 move()
是一种更简单的方法。 forward<T>
有效,但没有必要。