John K
John K

Reputation: 506

Why is my overloaded template function is promoting to const differently then a non-template function.

I have a overloaded function that works correctly. (f in the example). When I convert it to a template version of the same thing, it breaks by always calling the T& version, never the T*. (t in the example) When I make a non-const version of the template function it works as expected. (t2 in the example) This occurs in both VS2010 and g++ 4.6.2. Are the promotion to const rules different, or is this a bug of some sort.

#include <iostream>
using namespace std;

int f(const int&x){return 1;}
int f(const int*x){return 2;}

template <class T> int t(const T &x){return 3;}
template <class T> int t(const T *x){return 4;}

template <class T> int t2(T &x){return 5;}
template <class T> int t2(T *x){return 6;}

int main(int argc, char ** argv){
    int x=0;
    cout<<f(x)<<endl;
    cout<<f(&x)<<endl;
    cout<<t(x)<<endl;
    cout<<t(&x)<<endl;
    cout<<t2(x)<<endl;
    cout<<t2(&x)<<endl;
    return 0;
}

the output is

1
2
3
3
5
6

Upvotes: 4

Views: 135

Answers (2)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153840

Your int x isn't const. So &x yields an int*. Here are the two candidate functions:

  • int t<int*>(T const&) (equivalently int t<int*>(int * const&)) <-- T is int*; requires 0 conversions
  • int t<int>(T const*) (equivalently int t<int>(int const*)) <-- T is int; requires a conversion from int* to int const*

The better match, i.e. the one without a conversion, is chosen. That's the reference version.

Upvotes: 5

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272517

In these two cases:

cout<<t(x)<<endl;
cout<<t(&x)<<endl;

the template <class T> int t(const T &x) overload is being selected by the compiler, because T can be satisfied by int and int *, respectively.

In this case:

cout<<t2(&x)<<endl;

the template <class T> int t2(T &x) overload is not selected, because it cannot be satisfied. You cannot bind a reference to a temporary (rvalue), and &x is a temporary.

Upvotes: 2

Related Questions