Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

why template version is prefered in this case

0 views
Skip to first unread message

junvi

unread,
Aug 10, 2010, 3:41:57 PM8/10/10
to
#include <iostream>
using namespace std;

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! ]

CornedBee

unread,
Aug 12, 2010, 1:24:49 AM8/12/10
to
On Aug 10, 12:41 pm, junvi <junvi.b...@gmail.com> wrote:
> #include <iostream>
> using namespace std;
>
> 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

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

Daniel Krügler

unread,
Aug 12, 2010, 1:24:00 AM8/12/10
to
On 10 Aug., 21:41, junvi <junvi.b...@gmail.com> wrote:
> #include <iostream>
> using namespace std;
>
> 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

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

Florian

unread,
Aug 12, 2010, 3:03:38 AM8/12/10
to
On 10 aoūt, 21:41, junvi <junvi.b...@gmail.com> wrote:
> #include <iostream>
> using namespace std;
>
> 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

{ 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.

hak...@gmail.com

unread,
Aug 12, 2010, 3:01:59 AM8/12/10
to
On Aug 10, 3:41 pm, junvi <junvi.b...@gmail.com> wrote:
> #include <iostream>
> using namespace std;
>
> 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

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)

Ike Naar

unread,
Aug 12, 2010, 3:37:52 AM8/12/10
to
In article <48423290-31d8-4e62...@v15g2000yqe.googlegroups.com>,
junvi <junvi...@gmail.com> wrote:
> [...]

>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

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.

Jia-sen

unread,
Aug 12, 2010, 3:31:13 AM8/12/10
to
On Aug 10, 3:41 pm, junvi <junvi.b...@gmail.com> wrote:
> #include <iostream>
> using namespace std;
>
> 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

{ 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.

red floyd

unread,
Aug 12, 2010, 9:15:09 AM8/12/10
to
On Aug 10, 12:41 pm, junvi <junvi.b...@gmail.com> wrote:
> #include <iostream>
> using namespace std;
>
> 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

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.

Christian Broom

unread,
Aug 12, 2010, 9:15:02 AM8/12/10
to
The code doesn't make much sense in general. As is, the specification
says that a pointer to null results in undefined behavior. My compiler
(VC++08) calls the template function instead. To be sure which
function you call, give 'a' a proper reference and use the form:

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.

Florian

unread,
Aug 12, 2010, 7:25:56 PM8/12/10
to
On 12 aoūt, 15:15, Christian Broom <soulbea...@gmail.com> wrote:
> The code doesn't make much sense in general. As is, the specification
> says that a pointer to null results in undefined behavior. My compiler
> (VC++08) calls the template function instead. To be sure which
> function you call, give 'a' a proper reference and use the form:

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).

0 new messages