Yet another template question :o(

J

John

Hi,

before I gouge my eyes out with a teaspoon, hopefully someone will be
able to shed some light on the black art of templates!

I've exhausted the search engine, FAQs, groups etc looking for an answer
but it seems that getting the right search phrase is also a bit of an
art ;o)

OK, so here is what I've got (simplified):

/*storage for our sonar message*/
template <class T>
class CSonarMsg
{
public:
CSonarMsg(){}
~CSonarMsg(){}

SonarMessageHeaderType m_hSonarHdr;
T m_hSonarData;

void getMsg(SonarMessageHeaderType& sonarHdr, T& sonarData)
{
memcpy(&sonarHdr, &m_hSonarHdr, sizeof(SonarMessageHeaderType));
memcpy(&sonarData, &m_hSonarData, sizeof(T));
}
};

/*driver class*/
class CETSSCtrl
{
public:
CETSSCtrl(){}
~CETSSCtrl(){}

CSonarMsg<SonarMessageStatusType> m_hSonarMsgStatus;
CSonarMsg<SonarMessagePingType> m_hSonarMsgPing;

template <typename T>
void getMsg(unsigned char msgType, SonarMessageHeaderType& sonarHdr,
T& sonarData);
}

and in the CETSSCtrl.cpp I have:

template <typename T>
void CETSSCtrl::getMsg(unsigned char msgType, SonarMessageHeaderType&
sonarHdr, T& sonarData)
{
switch(msgType)
{
case STATUS_TYPE:
m_hSonarMsgStatus.getMsg(sonarHdr, sonarData);
break;

case PING_TYPE:
m_hSonarMsgPing.getMsg(sonarHdr, sonarData);
break;
}
}


Now the GUI thread calls the driver classes getMsg function with the
correct parameters. This is where I got my first headache. I didn't know
much about templates and hence about the fact that you need to have the
code inline ( I also read that if you don't want to have the code in
your header you can declare the function prototype for each type you
will use at the top of the cpp file. I couldn't get this to work - maybe
down to my syntax so maybe someone can tell me how it should be written?)

Anyway, I put the code inline and I get a compile error in the switch
statement. If I call the getMsg function with the
SonarMessageStatusType type then it complains (rightly so) that it
cannot convert from SonarMessageStatusType to SonarMessagePingType in
the second case of the switch statement (even though it won't get into
there). I understand that it is complaining because I am using two types
of instantiated objects in this template function but only passing in
one type.

My Questions:

1) Is my code structure flawed (or to put it bluntly crap!)
2) should i should a <reinterpret_cast> for each case in the switch so
that each object is forced to accept the type that was defined for it?
3) Should I just ditch the whole getMsg template and use a normal
function with void pointers?

Any help greatly appreciated.

Regards,

John.

[NOTE: I've not supplied my real email address as I prefer to keep all
replies to the newsgroup so that everyone can share in the knowledge!]
 
R

red floyd

John said:
Hi,

before I gouge my eyes out with a teaspoon, hopefully someone will be
able to shed some light on the black art of templates!

I've exhausted the search engine, FAQs, groups etc looking for an answer
but it seems that getting the right search phrase is also a bit of an
art ;o)

OK, so here is what I've got (simplified):

/*storage for our sonar message*/
template <class T>
class CSonarMsg
{
public:
CSonarMsg(){}
~CSonarMsg(){}

SonarMessageHeaderType m_hSonarHdr;
T m_hSonarData;

void getMsg(SonarMessageHeaderType& sonarHdr, T& sonarData)
{
memcpy(&sonarHdr, &m_hSonarHdr,
sizeof(SonarMessageHeaderType));
memcpy(&sonarData, &m_hSonarData, sizeof(T));
}
};

/*driver class*/
class CETSSCtrl
{
public:
CETSSCtrl(){}
~CETSSCtrl(){}

CSonarMsg<SonarMessageStatusType> m_hSonarMsgStatus;
CSonarMsg<SonarMessagePingType> m_hSonarMsgPing;

template <typename T>
void getMsg(unsigned char msgType, SonarMessageHeaderType&
sonarHdr, T& sonarData);
}

and in the CETSSCtrl.cpp I have:

template <typename T>
void CETSSCtrl::getMsg(unsigned char msgType, SonarMessageHeaderType&
sonarHdr, T& sonarData)
{
switch(msgType)
{
case STATUS_TYPE:
m_hSonarMsgStatus.getMsg(sonarHdr, sonarData);
break;

case PING_TYPE:
m_hSonarMsgPing.getMsg(sonarHdr, sonarData);
break;
}
}


Now the GUI thread calls the driver classes getMsg function with the
correct parameters. This is where I got my first headache. I didn't know
much about templates and hence about the fact that you need to have the
code inline ( I also read that if you don't want to have the code in
your header you can declare the function prototype for each type you
will use at the top of the cpp file. I couldn't get this to work - maybe
down to my syntax so maybe someone can tell me how it should be written?)

Declare all your template function bodies in the header.
Anyway, I put the code inline and I get a compile error in the switch
statement.

What error?

See if you can pare it down to the minimum compilable (or in your case,
non-compilable with the error) example. And post the full thing.
> [redacted]
My Questions:

1) Is my code structure flawed (or to put it bluntly crap!)
We don't know, you didn't post enough.
2) should i should a <reinterpret_cast> for each case in the switch so
that each object is forced to accept the type that was defined for it? No.

3) Should I just ditch the whole getMsg template and use a normal
function with void pointers?

No! You want the type safety you get with templates.
 

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

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top