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!]
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!]