Consider the following example:
#include <iostream>
#include <vector>
template<typename T>
void foo( T && )
{
std::cout << "Common foo!\n";
}
template<typename T>
void foo( const std::vector<T> & )
{
std::cout << "Specialized foo!\n";
}
int main()
{
foo( 5 );
foo( std::vector { 5 } );
}
As far as I know, when an overload resolution of function templates takes place, the most specialized overload instance is preferred. Cppreference states:
Informally "A is more specialized than B" means "A accepts a subset of the types that B accepts".
To me it is pretty obvious that void foo( const std::vector<T> & ) is more specialized than void foo( T && ). However, the latest Clang and GCC does not seem to agree with me as I get the following output:
Common foo!
Common foo!
This gets fixed by either taking std::vector<T> by value or passing a constant lvalue reference explicitly without making the compiler bind a temporary to it. But why is it the case? Are reference categories considered to be of a higher priority when it comes to partial ordering?
foo(T &&)is an exact match.void foo( const std::vector<T> & )requires to addconst.