I was originally trying to write a wrapper class for std::vector
. I had a templated constructor, that forwards a parameter pack to imitate different constructors for std::vector
.
Then I decided to had some specialized/overloaded ones if a std::vector
was passed in it.
While writing it, I decided to try how different function overload and template specialization works with.
Here are the codes that I have:
template<typename Type>
struct myVec
{
template <typename ...Params>
myVec(Params&&... params)
:vec(std::forward<Params>(params)...)
{
std::cout << "Generic used\n";
}
template <>
myVec<std::vector<Type>&&>(std::vector<Type>&& params)
{
std::cout << "Specialization used\n";
}
myVec(std::vector<Type>& params)
{
std::cout << "Overload used\n";
}
private:
std::vector<Type> vec;
};
int main()
{
std::vector<int> v{1,2,3,4,5};
myVec<int> vec1(v); // Print "Overload Used"
myVec<int> vec2(std::vector<int> {1,2,3,4,5}); // Print "Specialization used"
// myVec<int> vec3(&v); // Error, attempting to use generic template,
// which attempt to search for std::vector(std::vector& vec), which does not exist
}
So my question would how exactly do they decide which constructors to use? I thought vec1
would use the generic template, and vec3
would use the the overload, but apparently those are not the cases.
Also seems like for my specialization, I could just replace the explicit template <std::vector<Type>&&>
to <std::vector<Type>>
to <>
, or just remove it all together, and they would all work the same for me?