The following errors due to the const int specialization:
#include <iostream>
using std::cout;
using std::endl;
template <typename T> void g(T val)
{
cout << "unknown" << endl;
}
template <> void g(int && val)
{
cout << "int &&" << endl;
}
template <> void g(const int && val)
{
cout << "const int &&" << endl;
}
template <> void g(int & val)
{
cout << "int &" << endl;
}
template <> void g(const int & val)
{
cout << "const int &" << endl;
}
template <> void g(int val)
{
cout << "int" << endl;
}
template <> void g(const int val) //redefinition here
{
cout << "const int" << endl;
}
int main() {}
error: redefinition of 'g'
template <> void g(const int val)
^
Why are T& and T&& distinct from const T& and const T&& but T is not distinct from const T?
Because top-level const-ness of function parameters is an implementation detail of the function. For example, the following is valid:
Since the argument is passed by value, the caller doesn’t really care whether the function is going to modify its own private copy. Therefore, top-level const-ness is not part of the function signature.
Note that this only applies to top-level const-ness!
intandint constare equivalent in a function prototype, as areint *andint * const. Butint *andint const *are not.