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.

Ответить @Bo Persson Score 11

std :: forward используется для пересылки параметра точно так, как он был передан функции.

Кажется, чтоstd::forward допустимо (хотя, если я перейду по ссылке в ответе, во всех примерах используются шаблонные функции).

Ответы на вопрос(1)

Ваш ответ на вопрос