Re: Function template + overloading + polymorphism

From: Howard Hinnant (hinnant_at_metrowerks.com)
Date: 03/05/05


Date: Sat, 05 Mar 2005 15:52:28 GMT

In article <1110035461.848248.135370@o13g2000cwo.googlegroups.com>,
 "Imre" <jrms@pager.hu> wrote:

> Why is the function template a better match for the call in the
> following code?
>
> And how could I write a version of F() that should be called if the
> argument is a pointer to a type that is derived from B, while the
> template version should be called for all other argument types?
>
> #include <iostream>
>
> using namespace std;
>
> struct B {};
> struct D: public B {};
>
> template <typename T>
> int F(T &t) { return 1; }
> int F(B *pb) { return 2; }
>
> int main(int argc, char* argv[])
> {
> D *pd = new D;
> int i = F(pd);
> cout << i << '\n'; // writes 1 (VC++ 7.1), I'd like to get 2
> return 0;
> }

The template is a better match because:

int F<D*>(D*&);

is a better match for a D* argument than:

int F(B*);

(no conversion from D* to B* required for the former.

If you have access to the incredibly useful utilities enable_if and
is_convertible (maybe look at www.boost.org) you could do something like
the listing below. I'm using Metrowerks which has these facilities
built in, and spells enable_if as restrict_to, and that's what I'm
posting so that I can post tested code:

#include <iostream>

using namespace std;

struct B {};
struct D: public B {};

template <typename T>
typename Metrowerks::restrict_to
<
    !Metrowerks::is_convertible<T, B*>::value,
    int
>::type
F(T &t) { return 1; }

int F(B *pb) { return 2; }

int main(int argc, char* argv[])
{
    D *pd = new D;
    int i = F(pd);
    cout << i << '\n'; // writes 2 for me
    return 0;
}

-Howard



Relevant Pages