Template where I need to know the type

J

Jacek Dziedzic

Hello!

In my code I have functions like

SendToNode(int dest_node; int i);
SendToNode(int dest_node; double d);
SendToNode(int dest_node; unsigned int u);

and so on, where the function body is the same for all
these overloaded functions, except for one line, which
depends on the type of the second argument to SendToNode,
i.e. this line looks (more or less) like

internal_send_function(dest_node, type_is_int);
internal_send_function(dest_node, type_is_double);
internal_send_function(dest_node, type_is_unsigned_int);

where "type_is_int" etc. are symbolic constants of type int.

The situation is I'm not much of an OOP programmer, still
it looks to me like my SendToNode function is a candidate for
a template. The problem is: how do I do the "branching" in the
template, depending on what the *type* of the argument is?
How do I determine the type of that argument? I tried googling
it up and found something called typeof(), but it looked as if
it was not a part of the standard (perhaps "yet").

Is this where the concept of traits comes into play? What's
the story behind this?

TIA,
- J.
 
N

NFish

Jacek said:
Hello!

In my code I have functions like

SendToNode(int dest_node; int i);
SendToNode(int dest_node; double d);
SendToNode(int dest_node; unsigned int u);

and so on, where the function body is the same for all
these overloaded functions, except for one line, which
depends on the type of the second argument to SendToNode,
i.e. this line looks (more or less) like

internal_send_function(dest_node, type_is_int);
internal_send_function(dest_node, type_is_double);
internal_send_function(dest_node, type_is_unsigned_int);

where "type_is_int" etc. are symbolic constants of type int.

The situation is I'm not much of an OOP programmer,

Lucky for you, templates don't have much to do with OOD.
still
it looks to me like my SendToNode function is a candidate for
a template. The problem is: how do I do the "branching" in the
template, depending on what the *type* of the argument is?

It's called partial specialization, I think. But it won't help you much
here.
How do I determine the type of that argument? I tried googling
it up and found something called typeof(),

typeof() is a gcc extension, I think.
but it looked as if
it was not a part of the standard (perhaps "yet").

Is this where the concept of traits comes into play? What's
the story behind this?

This seems pretty straightforward to me. Refactor your code into a
function that does the shared stuff, and then add the one line that
differs to each of the specialized functions. It appears that all you
want to do is pass an int that depends on the static type, so you can
use overloading.

enum eType { eUnknown, eInt, eUnsignedInt, eDouble };

void internal_send_function(int dest_node, enum eType type) {
/* stuff goes here */
}

void SendToNode(int dest_node, int i) {
internal_send_function(dest_node, eInt);
}

void SendToNode(int dest_node, unsigned int i) {
internal_send_function(dest_node, eUnsignedInt);
}

void SendToNode(int dest_node, double i) {
internal_send_function(dest_node, eDouble);
}

It's not clear from the code you showed, but it looks like you aren't
using the value of the passed in variable at all, which makes me
question what exactly you're doing.

-Peter
 
J

Jacek Dziedzic

NFish said:
[...]
This seems pretty straightforward to me. Refactor your code
into a function that does the shared stuff, and then add the one
line that
differs to each of the specialized functions. It appears that all you
want to do is pass an int that depends on the static type, so you
can
use overloading.

enum eType { eUnknown, eInt, eUnsignedInt, eDouble };

void internal_send_function(int dest_node, enum eType type) {
/* stuff goes here */
}

void SendToNode(int dest_node, int i) {
internal_send_function(dest_node, eInt);
}

void SendToNode(int dest_node, unsigned int i) {
internal_send_function(dest_node, eUnsignedInt);
}

void SendToNode(int dest_node, double i) {
internal_send_function(dest_node, eDouble);
}

Yes, but that still leaves me with a one-function-needed-
per-every-type mess. Even though these functions are now
reduced to one line, I thought that by some "template magic"
I could stuff all that together into one function that would
perhaps have some branches depending on the type of
the argument, but not individual extra functions for every
possible type that I'd use.
It's not clear from the code you showed, but it looks like you
aren't using the value of the passed in variable at all, which
makes me question what exactly you're doing.

Ah yes, that was only a simplification, but I indeed forgot
to include the variable itself in the argument list of
SendToNode...

- J.
 
H

Howard Hinnant

Jacek Dziedzic said:
Hello!

In my code I have functions like

SendToNode(int dest_node; int i);
SendToNode(int dest_node; double d);
SendToNode(int dest_node; unsigned int u);

and so on, where the function body is the same for all
these overloaded functions, except for one line, which
depends on the type of the second argument to SendToNode,
i.e. this line looks (more or less) like

internal_send_function(dest_node, type_is_int);
internal_send_function(dest_node, type_is_double);
internal_send_function(dest_node, type_is_unsigned_int);

where "type_is_int" etc. are symbolic constants of type int.

The situation is I'm not much of an OOP programmer, still
it looks to me like my SendToNode function is a candidate for
a template. The problem is: how do I do the "branching" in the
template, depending on what the *type* of the argument is?
How do I determine the type of that argument? I tried googling
it up and found something called typeof(), but it looked as if
it was not a part of the standard (perhaps "yet").

Is this where the concept of traits comes into play? What's
the story behind this?

Maybe something like:

template <class T>
void
internal_send_function(int dest_node, T);

template <>
void
internal_send_function(int dest_node, int i) {}

template <>
void
internal_send_function(int dest_node, double d) {}

template <>
void
internal_send_function(int dest_node, unsigned int u) {}

template <class T>
void
SendToNode(int dest_node, T t)
{
// common stuff
internal_send_function(dest_node, t);
// common stuff
}

-Howard
 

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
474,145
Messages
2,570,826
Members
47,373
Latest member
Desiree036

Latest Threads

Top