Почему vector::push_back
не берет ссылку на пересылку вместо двух перегрузок? Я читал, что единственная причина, по которой вы хотите перегрузить lvalues и rvalues, - это то, что ваши функции делают для них что-то по-другому, так как обе перегрузки vector::push_back
отличаются друг от друга, чем перемещение/копирование?
Почему существуют две перегрузки для vector:: push_back?
Ответ 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()
не является одним из тех времен.