template <typename T>
void f(const T a) {
cout<<"Template version."<<endl;
}
void f(const int* a) {
cout<<"Plain version."<<endl;
}
int main() {
int *a=0;
f(a);
return 0;
}
the output is Plain version., I don't understand why is the case
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Both plain f and f<const int*> are perfect matches for the given
argument. In this case, the standard specifies that the non-template
is to be preferred. This allows non-templates to override templates
for specific cases.
Sebastian
The template version is no perfect match. If you
want to make it a better match, you better declare
it as
template <typename T>
void f(T* a) { ... }
If a function template and a non-template function
equally compete, the non-template function is preferred
over the template. This means that in the slightly
changed definition
template <typename T>
void f(const T* a) { ... }
the non-template function will be chosen instead.
HTH & Greetings from Bremen,
Daniel Krügler
{ quoted clc++m banner removed; please do it yourself. -mod }
With gcc4.5, the output is Template Version, and it make me in
trouble, in my mind it could be Plain Version.
I thought compiler check declared functions (so no template) and
implicit conversion before try to match template, but it seems to be
little different : it try to match template declaration before use
implicit conversion.
const T (with T = int*) = int* const, not const int*, so the template
don't need conversion, so it's using. If you type int* cont instead of
const int*, it's the plain version witch is using.
This is my run of your code:
$ g++ main.cpp -o run
$ ./run
Template version.
$ g++ --version
g++ (GCC) 4.4.4 20100630 (Red Hat 4.4.4-10)
Calling plain ``f'' with ``a'' as an argument requires an implicit
conversion from ``int*'' to ``const int*'', while no conversion
is required for the templated f, so templated f is a better match.
Change the declaration of ``a'' in main to ``const int *a = 0;''
then plain ``f'' will be chosen.
{ quoted clc++m banner removed; please do it yourself. -mod }
The point is that non-const to const conversion is still a conversion.
The argument 'a' is non-const, so template version matches better than
the plain one. Try define 'a' as 'const int* a=0' and see which
version is called.
Your question doesn't make sense. You ask "Why template version is
preferred". it's not. You get the non-template version, as you
should.
f<T>(a) // Specifically call the template function with a type T.
To be really sure which function is called, don't be silly enough to
declare two functions with the same name. It is usually a sign of bad
design and merits refactoring.
Use a NULL pointer is a UB, but here the pointer isn't use (juste
define), so there isn't UB, just normal behavior.
> To be really sure which function is called, don't be silly enough to
> declare two functions with the same name. It is usually a sign of bad
> design and merits refactoring.
Overload template function is a good solution to solve the problem of
partial specialization, so have two functions with the same name could
be good (and I thing that overload is better than specialization for
template function, but I don't find a good source which explains that,
perhaps the book of Alexandrescu and Sutter).