I'm trying to implement std::vector all by myself for some exercising purposes. My question is about the push_back(..) methods. There are two overloads of this method as in the following.
void push_back(const value_type& value);
void push_back(value_type&& value);
At first, I implemented them in two different functions. For the former one, I choose to copy construct the new element with the given value. And for the latter one, I choose to move construct the new element with the given value. Here are the implementations of mine:
template<class T>
void Vector<T>::push_back(const value_type& value)
{
if(size() == capacity()) // Size is about to surpass the capacity
grow(nextPowerOf2(capacity()), true); // Grow and copy the old content
new(data + sz++) value_type(value); // Copy construct new element with the incoming one
}
template<class T>
void Vector<T>::push_back(value_type&& value)
{
if(size() == capacity()) // Size is about to surpass the capacity
grow(nextPowerOf2(capacity()), true); // Grow and copy the old content
new(data + sz++) value_type(std::move(value)); // Move construct new element with the incoming
}
After then, I realized that I could merge these two functions in a single method that takes a universal reference such as in the following code:
template<class T>
template<class U>
void Vector<T>::push_back(U&& value)
{
if(size() == capacity()) // Size is about to surpass the capacity
grow(nextPowerOf2(capacity()), true); // Grow and copy the old content
// Construct new element with the incoming
new(data + sz++) value_type(std::forward<U>(value));
}
I think this single method handles all the things that I was trying to do with two different methods. Is there a thing that I'm missing? Will this operation bother me later? I don't seek backward compatibility, so you can omit it.