Why is the test version specialized for rvalue argument not being used?
This is because the function argument std::forward<mytype>(stuff)
that you're passing is an expression and an expression in C++ is never of some reference type. That is, the type of the function call argument std::forward<mytype>(stuff)
is actually std::vector<std::string>
and not std::vector<std::string>&&
. In other words, T
will be deduced as std::vector<std::string>
and not std::vector<std::string>&&
.
Basically, you've specialized the function template for the template argument std::vector<std::string>&&
but T
gets deduced to std::vector<std::string>
. Thus, the specialization cannot be used. On the other hand, if you were to removed the &&
then the specialization will be called(see explanation at the end of the answer).
Lets look at a contrived example to clear this up:
Example 1
I am adding the following example to show that my above explanation is correct.
template <class T> void f(T)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void g() {
f((const int&)0); //T will be deduced as int and not "const int" or even "const int&"
f((int&&)0); //T will be deduced as int and not "int&&"
}
int main()
{
g();
return 0;
}
Working demo.
Example 2
template<typename T>
void test(T item) //#1
{
std::cout<<"generic"<<std::endl;
}
template<>
void test(int&& vec) //#2
{
std::cout<<"Ok."<<std::endl;
}
int main()
{
int stuff = 0;
//---vvvvvvvvvvvvvvvvvvvvvvvv----------->the argument is an expression and is of type int instead of int&&
test(std::forward<int>(stuff)); //calls #1
}
In the above example the expression std::forward<int>(stuff)
is of type int
and not int&&
, therefore T
is deduced as int
(and not int&&
). This means the generic version will be called.
removing && will make that happen
When you remove the &&
, then this time you're explicitly specializing the function template for std::vector<std::string>
and not std::vector<std::string>&&
. This means that this time, the deduced T
matches the template argument for which you've specialized the function template and so the specialization is called.