Deciding execution path based on template parameters?

S

Sachin Garg

I was trying something with templates in C++, can't figure out if it is
possible.

Can I check in a function what template parameter was passed, and then
decide what to do?

for example...

I have two simple types:

struct x {int a, b, c};
struct y {int x};

A template class is defined with
template<class T>

then in one of the member functions, I want to do

if(T==x) { do something with a, b and c}
if(T==y) { do something with x}

(These ifs need to be resolved at compile time, else the code wont
compile.)

Something similar can be done through template specialization, but I
was hoping if such if/else is possible.

I can do if(typeid(T ) == typeid(x))

but this is resolved at run time... I want something which gets
resolved at compile time. To avoid the performance hit.


I can think of a work around....

template<int t_id, class T>

and then in code...

if(t_id==x_id) { do stuff for x}
if(t_id==y_id) { do stuff for y}

(here x_id and y_id are constants)


Only problem is that now t_id and T essentially mean the same thing, so
its kinda redundant to specify both. But this should work


Templates can have if else on value parametres which get solved at
compile time, I was just hoping if it can do that with type parameters
too.

Technically this seems to be possible. What will be the best option in
this case, any alternates you can suggest.


Sachin Garg [India]
www.sachingarg.com | www.c10n.info
 
J

Jerry Coffin

I was trying something with templates in C++, can't figure out if it is
possible.

Can I check in a function what template parameter was passed, and then
decide what to do?

for example...

I have two simple types:

struct x {int a, b, c};
struct y {int x};

A template class is defined with
template<class T>

then in one of the member functions, I want to do

if(T==x) { do something with a, b and c}
if(T==y) { do something with x}

This is done somewhat differently. You start by writing a template that
works for types in general (though in some cases, the general version is
never intended to be used, and may intentionally cause an error so it
_can't_ be used).

Then you write a specialization for the types that receive special
treatement:

template <class T>
class XYZ {
// whatever
};

template <>
class XYZ<x> {
// do something with a, b, c
};

template <>
class XYZ<y> {
// do something with x
};

This is handled by compile time -- but it does NOT (directly) support
writing only _part_ of the template in a specialized fashion -- you have
to reproduce the specialized template in general. If you want to
specialize only part, you need to split that part out into a separate
template of its own.
 
S

Sachin Garg

Jerry said:
This is done somewhat differently. You start by writing a template that
works for types in general (though in some cases, the general version is
never intended to be used, and may intentionally cause an error so it
_can't_ be used).

Then you write a specialization for the types that receive special
treatement:

template <class T>
class XYZ {
// whatever
};

template <>
class XYZ<x> {
// do something with a, b, c
};

template <>
class XYZ<y> {
// do something with x
};

This is handled by compile time -- but it does NOT (directly) support
writing only _part_ of the template in a specialized fashion -- you have
to reproduce the specialized template in general. If you want to
specialize only part, you need to split that part out into a separate
template of its own.

My goal behind using templates here is to avoid duplicated code :)

I guess I will try using the t_id approach I mentioned and see how it
goes.

Thanks,
Sachin Garg [India]
www.sachingarg.com | www.c10n.info
 
J

Jerry Coffin

[ ... ]
My goal behind using templates here is to avoid duplicated code :)

Right -- if you only have a few things in a few places that depend on
the type, you can still use templates, but factor those few bits into
their own functions (or functors) and supply that as a template
parameter:

struct x { int a, b, c; };
strut y { int x; };

struct x_spec {
void operator()(x const &xx) {
// do something with x
}
};

struct y_spec {
void operator()(y const &yy) {
// do something with y
}
};

template <class T, class special>
class whatever {
T t;
public:
void member1() {
special()(t); // code specialized for one type
}

void member2() {
// code for either type
}
};

This depends, however, on being able to factor the specialized behavior
into a relatively small number of specialized functions. If you have
lots of different type-dependencies spread throughout the code, it's
probably not going to work very well -- but then again, that starts to
sound like what you have may not have enough commonality to really gain
a lot from code sharing in any case. In a case like that, instead of a
class template, you might be better off with a few function templates to
provide a common code base for the things that really are the same
across the types.
 

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,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top