Why doesn't vector::push_back
take a forwarding reference instead of having two overloads? I've read that the only reason you'd want to overload on lvalues and rvalues is if your functions do something differently for them, so how do both overloads of vector::push_back
differ other than moving/copying?
C++ Vector Library - push_back() Function The C++ function std::vector::push_back() inserts new element at the end of vector and increases size of vector by one.
push_back method() in C++ is a method that is part of the vector as a data structure in C++. It is used for pushing elements from the back of the vector.
Yes, std::vector<T>::push_back() creates a copy of the argument and stores it in the vector.
The push_back() function is used to insert an element at the end of a vector. This function is available in the <vector> header file.
I did this largely just because of how the situation evolved. Prior to C++11, there was only:
vector<T>::push_back(const T&);
With the introduction of rvalue references I recommended the addition of the overload:
vector<T>::push_back(T&&);
instead of changing the original signature to:
template <class U> vector<T>::push_back(U&&);
Part of this decision was made because of some concerns about backward compatibility (whether warranted or not), and to ease concerns of both vendors and others on the committee that this was a simple addition of functionality, and not a change to existing functionality.
If I were redesigning vector
from scratch today, I would seriously consider just having:
template <class U> vector<T>::push_back(U&&);
or perhaps just:
template <class ...Args> vector<T>::emplace_back(Args&& ...);
More details than you probably want to know about are in N1858.
Why not push_back
by value?
This question has been marked as a duplicate of:
Why do C++11 std containers have pass-by-ref and pass-by-rvalue insert/push methods?
which asks this question. So I figured it would be the polite thing to do to actually address that aspect in this answer...
For lvalues and xvalues, a push_back(T)
would cost an extra move construction compared to the by-reference solutions. xvalues would require 2 move constructions and lvalues would require 1 copy construction and 1 move construction.
In contrast, with the current design, lvalues cost 1 copy construction and xvalues cost 1 move construction.
For some types T
, move construction is not cheap. It would be a poor design choice for vector<T>
to assume that T
is always cheaply movable. For example what if T
is std::array<double, 100>
? Changing to the by-value design would require 2 copy constructions instead of 1 to push_back
(except for prvalues).
The by-value solution does have advantages, and times when it should be used. It is just that vector<T>::push_back()
is not one of those times.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With