Reputation: 506
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
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 conversionsint 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
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