Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compilation error in template when const is removed

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.

like image 413
nvn Avatar asked Aug 11 '26 16:08

nvn


1 Answers

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 &'
}
like image 119
wohlstad Avatar answered Aug 13 '26 11:08

wohlstad