473,398 Members | 2,427 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

Function template + overloading + polymorphism


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;
}

Thanks.

Imre

Jul 23 '05 #1
4 1400
In article <11**********************@o13g2000cwo.googlegroups .com>,
"Imre" <jr**@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
Jul 23 '05 #2
"Imre" <jr**@pager.hu> wrote...

Why is the function template a better match for the call in the
following code?
Essentially, F<> is a better match because it deduces that T is
'D*' and since the forma argument is a reference and the actual
argument is an l-value, there is no conversion involved. For the
F(B*) a derived-to-base conversion (standard conversion) is needed.
No conversion is preferred to any conversion.
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?
I am not sure you can.

If your intention is to somehow figure out that the type you have
('D' in your case) is a derived type of 'B', then you just neen to
look at the 'is_base_and_derived' template from Boost library.
#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;
}


V
Jul 23 '05 #3
Imre 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;
}

Thanks.

Imre

i suppose you could do something like this:

template <typename T>

int F(T &t)
{
T *pt = &t;
B *pB = dynamic_cast<T*>(pt);
if(pB)
{
return F(pB);// Calls F(B *pB);
}
}

I'm not sure it works. I didn't test it.
Remeber to turn on the Run Time Type Information to your compiler.
If you use VC++ 7.1 it's somewhere in the Compiler setting
Jul 23 '05 #4
Kostas Katsamakas wrote:
Imre 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;
}

Thanks.

Imre

i suppose you could do something like this:

template <typename T>

int F(T &t)
{
T *pt = &t;
B *pB = dynamic_cast<T*>(pt);
if(pB)
{
return F(pB);// Calls F(B *pB);
}
}

I'm not sure it works. I didn't test it.
Remeber to turn on the Run Time Type Information to your compiler.
If you use VC++ 7.1 it's somewhere in the Compiler setting


I made a mistake above.
the correct line is :
B *pB = dynamic_cast<B*>(pt);
Jul 23 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Dave Theese | last post by:
Hello all, I'm trying to get a grasp of the difference between specializing a function template and overloading it. The example below has a primary template, a specialization and an overload. ...
7
by: Hendrik Schober | last post by:
Hi, I have a problem, that boils down to the following code: #include <iostream> #include <typeinfo> class Test1 {}; class Test2 {}; class Test3 {};
12
by: Joe | last post by:
Hi, Can I pass a "generic" class pointer as an argument to a function? For instance say classA and B are both derived from Z. { int iType =1;
16
by: WittyGuy | last post by:
Hi, What is the major difference between function overloading and function templates? Thanks! http://www.gotw.ca/resources/clcm.htm for info about ]
22
by: Ian | last post by:
The title says it all. I can see the case where a function is to be called directly from C, the name mangling will stuff this up. But I can't see a reason why a template function can't be...
6
by: flopbucket | last post by:
Could someone explain to me what the difference is between function template specialization and function overloading? I guess overloading can change the number of parameters, but otherwise they...
11
by: placid | last post by:
Hi all, Is it possible to be able to do the following in Python? class Test: def __init__(self): pass def puts(self, str): print str
2
by: rn5a | last post by:
I use VB.NET to create ASP.NET apps. If I am not wrong, there is something called method overloading in VB.NET (like in C#) which is one of the features in OOP (polymorphism) but does VB.NET also...
14
by: mesut | last post by:
hi colleagues, I don't know if this is the right group for but it's in C# so I try. I have a #3 procedural function called GetInfo.. and those are 3 overloaded methods. I would like to use the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.