everyone!
I have a template function named UpdateValue, which was designed to update some values with different types such as integer, BOOL, string, and so on. Please see the following code snippet for your reference:
#include <typeinfo.h>
template<class T>
void UpdateValue(T Value)
{
if ( typeid(int) == typeid(Value) )
{
ZOrder(Value);
}
else if ( typeid(bool) == typeid(Value) )
{
BOOL bShow = Value ? TRUE : FALSE;
Show(bShow);
}
else if ( typeid(CString) == typeid(Value) )
{
Theme(Value);
}
}
void Show(BOOL bShow) { m_bShow = bShow; }
void ZOrder(int nZOrder) { m_nZOrder = nZOrder; }
void Theme(CString strTheme) { m_strTheme = strTheme; }
BOOL m_bShow;
int m_nZOrder;
CString m_strTheme;
But when I use the following statements to call this kind of template function
CString strValue = _T("Animal");
UpdateValue<CString>(strValue);
the aforesaid code failed to compile by throwing the following exceptions:
e:\dynaprop\dynaprop\mainfrm.cpp(269) : error C2664: ‘CMainFrame::ZOrder’ : cannot convert parameter 1 from ‘CString’ to ‘int’
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> e:\dynaprop\dynaprop\mainfrm.cpp(67) : see reference to function template instantiation ‘void CMainFrame::UpdateValue(T)’ being compiled
1> with
1> [
1> T=CString
1> ]
Would you please show me how to figure it out? Thank you in advance!
You are not really using the template facilities. Or rather miss using it. What happens is you call the
ZOrder(Value)thevoid UpdateValue(T Value)get instantiated where every occurence ofTgets replaced withCStringas you specified. But that is all.The function look like this
After the template gets instantied the normal compiling stuff happens … and you get an error ’cause it is written
ZOrder(Value);wherevalueis ofCStringtype. This will produce an error, even though utilizing RTTI this call path should never be reached in such case.What you should do is to use specializations to handle different types. Try replacing original definition of
UpdateValuewith these:Then when you call
UpdateValue< T >you invoke version with appropriate body. also you don’t have to use RTTI.UPDATE: After the commenter suggestion. If you do not need/want to the handle general case (i.e. unknown type), you can resort to plain overloads and go with:
No need even for templates then!