Template function and dynamic_cast

R

richardclay09

Please take a look at this method:

template<class C> void f(C* ptrAny) {
Fruit* ptrFruit = dynamic_cast<Fruit*>(ptrAny);
if(ptrFruit) {
// do something specific to fruits
}
// Carry on using ptrAny whatever it is
}

So I have a template function, but for Fruits I also want to do a
certain specific thing.
All is well and good until I happen to call F with a non-polymorphic
type. Then it barfs with a compile error.

So how can I do this where the templated C type can be polymorphic or
not? NB I don't want to overload f with a non-template like this:
void f(Fruit* ptrFruit) {...}
....because I have several templated functions like f, and also because
how would the compiler know which one to call for a Fruit, the
Fruit-specific one or the templated one instantiated for a Fruit?

Thanks for any help.
 
D

Dan Cernat

Please take a look at this method:

template<class C> void f(C* ptrAny) {
Fruit* ptrFruit = dynamic_cast<Fruit*>(ptrAny);
if(ptrFruit) {
// do something specific to fruits
}
// Carry on using ptrAny whatever it is
}

So I have a template function, but for Fruits I also want to do a
certain specific thing.
All is well and good until I happen to call F with a non-polymorphic
type. Then it barfs with a compile error.

So how can I do this where the templated C type can be polymorphic or
not? NB I don't want to overload f with a non-template like this:
void f(Fruit* ptrFruit) {...}

I think you have no choice. "Specialization" is the name of the game.
...because I have several templated functions like f
so what?
, and also because
how would the compiler know which one to call for a Fruit, the
Fruit-specific one or the templated one instantiated for a Fruit?

the compiler is smart enough to pick the specialized function instead
of the templated one
Thanks for any help.

see the code below:

class Fruit
{
public:
void IsRipe(){}
virtual ~Fruit(){}
};

class NonF
{
};

template <class C>
void f_impl(C* ptrAny)
{
// do the common stuff
}

template<class C>
void f(C* ptrAny)
{
// do the common processing
f_impl(ptrAny);
}

template<>
void f(Fruit* ptrFruit)
{
// do something specific for fruit
ptrFruit->IsRipe();

// then, do the common processing
f_impl(ptrFruit);
}

int main()
{
Fruit fr;
NonF nf;

f(&fr);
f(&nf);

return 0;
}

/dan
 
T

Tobias Blomkvist

(e-mail address removed) sade:
void f(Fruit* ptrFruit) {...}
...because I have several templated functions like f, and also because
how would the compiler know which one to call for a Fruit, the
Fruit-specific one or the templated one instantiated for a Fruit?

Then perhaps a template specialization, no compiler confusion there.

template<typename T> void f(T *) {}

template<> void f(Fruit *) {}

Tobias
 
B

benben

Please take a look at this method:

template<class C> void f(C* ptrAny) {
Fruit* ptrFruit = dynamic_cast<Fruit*>(ptrAny);
if(ptrFruit) {
// do something specific to fruits
}
// Carry on using ptrAny whatever it is
}

So I have a template function, but for Fruits I also want to do a
certain specific thing.
All is well and good until I happen to call F with a non-polymorphic
type. Then it barfs with a compile error.

So how can I do this where the templated C type can be polymorphic or
not? NB I don't want to overload f with a non-template like this:
void f(Fruit* ptrFruit) {...}
...because I have several templated functions like f, and also because
how would the compiler know which one to call for a Fruit, the
Fruit-specific one or the templated one instantiated for a Fruit?

Thanks for any help.

Why don't you do:

void f(Fruit* ptrFruit)
{
FruitSpecific();
f<Fruit>();
}

template <typename T>
void f(T* ptrAny)
{
// carry on
}

Ben
 
P

peter.koch.larsen

Dan Cernat skrev:
I think you have no choice. "Specialization" is the name of the game.

so what?

Well, that is the problem. At least if you assume the OP's dynamic_cast
made any sense at all.
the compiler is smart enough to pick the specialized function instead
of the templated one


see the code below:

Your code is wrong - see below.
class Fruit
{
public:
void IsRipe(){}
virtual ~Fruit(){}
};

class NonF
{
};

template <class C>
void f_impl(C* ptrAny)
{
// do the common stuff
}

template<class C>
void f(C* ptrAny)
{
// do the common processing
f_impl(ptrAny);
}

template<>
void f(Fruit* ptrFruit)
{
// do something specific for fruit
ptrFruit->IsRipe();

// then, do the common processing
f_impl(ptrFruit);
}

int main()
{
Fruit fr;
NonF nf;

f(&fr);
f(&nf);

return 0;
}

The problem is that you suppose that fruit is the base class, but it
can not be as there would then be no reason to use a dynamic cast.

Change you program as follows:

class Edible
{
virtual ~Edible();
};

class Fruit: Edible;

....
Edible *e = new Fruit();
f(e);


/Peter
 
P

peter.koch.larsen

(e-mail address removed) skrev:
Please take a look at this method:

template<class C> void f(C* ptrAny) {
Fruit* ptrFruit = dynamic_cast<Fruit*>(ptrAny);
if(ptrFruit) {
// do something specific to fruits
}
// Carry on using ptrAny whatever it is
}

So I have a template function, but for Fruits I also want to do a
certain specific thing.
All is well and good until I happen to call F with a non-polymorphic
type. Then it barfs with a compile error.

You need to use template metaprogramming if indeed that is what you
want. Look at boost for the needed tools (the library is called mpl).
So how can I do this where the templated C type can be polymorphic or
not? NB I don't want to overload f with a non-template like this:
void f(Fruit* ptrFruit) {...}
...because I have several templated functions like f, and also because
how would the compiler know which one to call for a Fruit, the
Fruit-specific one or the templated one instantiated for a Fruit?

If Fruit is a base-class (e.g. you intend to call it with a class
Banana: public Fruit), then the nontemplated function is the way to go.
That presumes that your dynamic_cast was wrong. If it is the other way
around (e.g. class Fruit::public Edible) you should either create a
function void f(Edible* e) and direct your non-fruit calls to the
generic class or take the templateroute as you seem to be determined to
use. I just do not see how templates give you anything here.
Thanks for any help.

/Peter
 
B

benben

Tobias Blomkvist said:
(e-mail address removed) sade:

Then perhaps a template specialization, no compiler confusion there.

template<typename T> void f(T *) {}

template<> void f(Fruit *) {}

Tobias

--
IMPORTANT: The contents of this email and attachments are confidential
and may be subject to legal privilege and/or protected by copyright.
Copying or communicating any part of it to others is prohibited and may
be unlawful.

Is it a new standard that function templates can be specialized? What is

template<> void f(Fruit*){}

supposed to differ from

void f(Fruit*){}

??

Ben
 
B

benben

Tobias Blomkvist said:
(e-mail address removed) sade:

Then perhaps a template specialization, no compiler confusion there.

template<typename T> void f(T *) {}

template<> void f(Fruit *) {}

Tobias

--
IMPORTANT: The contents of this email and attachments are confidential
and may be subject to legal privilege and/or protected by copyright.
Copying or communicating any part of it to others is prohibited and may
be unlawful.

Is it a new standard that function templates can be specialized? What is

template<> void f(Fruit*){}

supposed to differ from

void f(Fruit*){}

??

Ben
 
T

Tobias Blomkvist

benben sade:
Is it a new standard that function templates can be specialized? What is

C++ Standard §14.7
template<> void f(Fruit*){}

supposed to differ from

void f(Fruit*){}

??

Ben

My reply wasn't the best in that context, I admit.

But you could separate them:

Fruit * g = new Fruit;
f<Fruit>(g); // calls template specialization

Tobias
 
B

benben

C++ Standard §14.7
My reply wasn't the best in that context, I admit.

But you could separate them:

Fruit * g = new Fruit;
f<Fruit>(g); // calls template specialization

Tobias

It seems to be a fairly new standard because I couldn't find it in both
Bjarne's and Nicolai's books (or I just missed that part.) But I still don't
have an idea how is function template specialization different from simple
function overloading. It seems to me they are really the same but I doubt.

Any hint would be much appreciated!

Ben
 
T

Tobias Blomkvist

benben sade:
It seems to be a fairly new standard because I couldn't find it in both
Bjarne's and Nicolai's books (or I just missed that part.) But I still don't

Depends on if you call the first C++ standard ISO/IEC 14882:1998
from 1998 new or not. If you don't have it, you could
always scout the final draft on templates, available all over
the internet:

http://www.kuzbass.ru:8086/docs/isocpp/template.html

Tobias
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top