std :: move против std :: forward
Похоже, это самый актуальный вопрос, который уже задавался.
В чем разница между std :: move и std :: forward
Но каждый ответ разный, применим и говорит немного разные вещи. Так что я в замешательстве.
У меня следующая ситуация.
Скопировать товар в контейнерЭлемент Copy - C ++ 03, так что я это хорошо понимаю.Построить предмет в контейнер
Я полагаю, что элемент Construct в контейнер использует совершенную пересылку правильно для пересылки аргументов через две функции в конструктор T в
emplaceBackInternal()
(Пожалуйста, скажите иначе, если я ошибаюсь).Переместить элемент в контейнерКажется, моя проблема заключается в понимании перемещения предмета в контейнер.
Код:
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
выглядит так похоже, что кажется, что они должны быть одинаковыми.
Ответить @Potatoswatter Score 67
У std :: forward есть один вариант использования:параметр шаблонной функции
По этому определению я должен использоватьstd::move
внутриpush_back(T&& value)
а такжеmoveBackInternal(T&& value)
поскольку значение не является параметром шаблона для функции.
Ответить @Howard Hinnant Score 38
Если Y является ссылкой lvalue, результатом будет выражение lvalue.Если Y не является ссылкой lvalue, результатом будет rvalue (xvalue, чтобы быть точным) выражение.
Кажется, по этому определению я могу использовать либоstd::move
или жеstd::forward
.
std :: forward используется для пересылки параметра точно так, как он был передан функции.
Кажется, чтоstd::forward
допустимо (хотя, если я перейду по ссылке в ответе, во всех примерах используются шаблонные функции).