template<typename T>
void func(const T &x) {
cout << "base template "<<x<<"\n";
}
template<>
void func(const int &x) {
cout << "int specialization "<<x<<"\n";
}
template<>
void func(const double &x) {
cout << "double specialization "<<x<<"\n";
}
int main() {
int five = 5;
func(five); // prints int specialization 5
double d = 3.14;
func<int>(d); // prints int specialization 3
}
Now with const
removed
template<typename T>
void func( T &x) {
cout << "base template "<<x<<"\n";
}
template<>
void func( int &x) {
cout << "int specialization "<<x<<"\n";
}
template<>
void func( double &x) {
cout << "double specialization "<<x<<"\n";
}
int main() {
int five = 5;
func(five); // prints int specialization 5
double d = 3.14;
func<int>(d); // throws compile error
}
Why do I get a compilation error in func<int>(d)
where as in the const
version everything compiled fine ?
Error C2664 'void func(int &)': cannot convert argument 1 from 'double' to 'int &'
I came across this when I was trying out some examples on my own for template specialization.
I'm looking for reading links and posts that might be helpful.
The issue is not actually related to templates:
Your double d
needs to be converted to an int
in order to be an argument for a function expecting an int
reference.
But since the converted int
is a temporary (i.e. a R-value) it cannot be bound to an int &
, but only to a const int &
.
You can observe this without any template:
void func1(const int& x)
{
}
void func2(int& x)
{
}
int main()
{
double d = 3.14;
func1(d); // This compiles.
func2(d); // This does not. Error on MSVC: cannot convert argument 1 from 'double' to 'int &'
}