Подтвердить что ты не робот

Почему существуют две перегрузки для vector:: push_back?

Почему vector::push_back не берет ссылку на пересылку вместо двух перегрузок? Я читал, что единственная причина, по которой вы хотите перегрузить lvalues ​​и rvalues, - это то, что ваши функции делают для них что-то по-другому, так как обе перегрузки vector::push_back отличаются друг от друга, чем перемещение/копирование?

4b9b3361

Ответ 1

Я сделал это в основном только из-за того, как сложилась ситуация. До С++ 11 было только:

vector<T>::push_back(const T&);

С введением ссылок rvalue я рекомендовал добавление перегрузки:

vector<T>::push_back(T&&);

вместо изменения исходной подписи на:

template <class U> vector<T>::push_back(U&&);

Часть этого решения была сделана из-за некоторых опасений относительно обратной совместимости (независимо от того, оправданы они или нет), и чтобы облегчить озабоченность как поставщиков, так и других членов комитета, что это простое дополнение функциональности, а не изменение существующих функциональность.

Если бы я сегодня менял дизайн vector с нуля, я бы серьезно подумал, что у него есть:

template <class U> vector<T>::push_back(U&&);

или, возможно, просто:

template <class ...Args> vector<T>::emplace_back(Args&& ...);

Более подробная информация, чем вы, вероятно, хотите узнать, находится в N1858.

Почему не push_back по значению?

Этот вопрос был отмечен как дубликат:

Почему в контейнерах С++ 11 std есть методы ввода/высылки pass-by-rvalue?

который задает этот вопрос. Поэтому я решил, что это будет вежливое дело, чтобы фактически решить этот аспект в этом ответе...

Для lvalues ​​и xvalues ​​a push_back(T) будет стоить дополнительной конструкции перемещения по сравнению с решениями для сравнения. xvalues ​​потребует 2 перемещения конструкций и lvalues ​​потребуется 1 копия строительства и 1 двигаться строительства.

Напротив, при нынешнем дизайне lvalues ​​стоит 1 копия, а стоимость xvalues ​​стоит 1 шаг строительства.

Для некоторых типов T перемещение конструкции не из дешевых. Было бы плохой выбор дизайна для vector<T>, чтобы предположить, что T всегда дешево перемещается. Например, что, если T - std::array<double, 100>? Для изменения значения по умолчанию потребуется 2 копии конструкций вместо 1 до push_back (за исключением prvalues).

Решение по стоимости имеет преимущества и время, когда оно должно использоваться. Просто vector<T>::push_back() не является одним из тех времен.