This seems to be most relavant question already asked.
Whats the difference between std::move and 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. - 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 inemplaceBackInternal()
(Please say otherwise if I am wrong). - 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.
Answer @Potatoswatter Score 67
std::forward has a single use case: to cast a templated function parameter
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.
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.
Seems by this definition I can use either std::move
or std::forward
.
std::forward is used to forward a parameter exactly the way it was passed to a function.
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
is for forwarding references and the third additionally spends some time explain whatstd::forward
is. – Turnsole