大家好!
我有一个名为UpdateValue的模板函数,它用于更新一些不同类型的值,如integer,BOOL,string等。请参阅以下代码段供您参考:
#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;
但是当我使用以下语句来调用这种模板函数时
CString strValue = _T("Animal");
UpdateValue<CString>(strValue);
上述代码未能通过抛出以下异常进行编译:
e:\ dynaprop \ dynaprop \ mainfrm.cpp(269):错误C2664:'CMainFrame :: ZOrder':无法将参数1从'CString'转换为'int' 1 GT;没有可用于执行此转换的用户定义转换运算符,或者无法调用运算符 1 GT; e:\ dynaprop \ dynaprop \ mainfrm.cpp(67):参见函数模板实例化'void CMainFrame :: UpdateValue(T)'被编译 1 GT;同 1 GT; [ 1 GT; T = CString的 1 GT; ]
请您告诉我如何解决这个问题?提前谢谢!
答案 0 :(得分:1)
您实际上并没有使用模板工具。或者更确切地说错过使用它如果ZOrder(Value)
获得void UpdateValue(T Value)
实例化,T
每次出现的CString
都会被您指定的void UpdateValue(CString 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);
}
}
替换,会发生什么情况。但就是这样。
该功能看起来像这样
ZOrder(Value);
在模板立即生效后,正常的编译内容会发生......并且您会收到错误,因为它是value
CString
UpdateValue
类型的template<> // specialization when T is get to be int
void UpdateValue<int>(int Value) { ZOrder(Value);};
template<> // specialization when T is get to be CString
void UpdateValue<bool>(bool Value) { BOOL bShow = Value ? TRUE : FALSE; Show(bShow);};
template<> // specialization when T is get to be CString
void UpdateValue<CString>(CString Value) { Theme(Value);};
template<class T> //general case
void UpdateValue(T Value) { cout << "IMPLEMENT ME\n";};
。这将产生错误,即使使用RTTI,在这种情况下也不应该达到此调用路径。
您应该使用专业化来处理不同类型。尝试使用以下内容替换UpdateValue< T >
的原始定义:
//Value is int
void UpdateValue(int Value) { ZOrder(Value);};
//Value is bool
void UpdateValue(bool Value) { BOOL bShow = Value ? TRUE : FALSE; Show(bShow);};
//Value is CString
void UpdateValue(CString Value){ Theme(Value);};
然后,当您调用{{1}}时,您调用具有适当正文的版本。你也不必使用RTTI。
更新:在评论者的建议之后。如果你不需要/想要处理一般情况(即未知类型),你可以诉诸普通的重载并使用:
{{1}}
然后甚至不需要模板!
答案 1 :(得分:0)
如某些其他答案中所述(或暗示),您需要将三个代码分支分成三个模板特化 - 每个参数类型一个。但这很愚蠢;如果你真的想要一个UpdateValue
函数根据参数类型做三个不同的事情,那么只需编写UpdateValue
的三个重载并且根本不使用模板!
(这可能无法使用BOOL
类型,因为它可能也是int
。您最有可能使用bool
,除非有一些非常强大 - 并且奇怪 - 不这样做的原因。)
答案 2 :(得分:0)
你可以使用函数重载来实现我想要做的事情,我想, (我将其更改为使用STL字符串,以便我可以编译):
#include <typeinfo>
#include <string>
using namespace std;
bool m_bShow;
int m_nZOrder;
string m_strTheme;
void Show(bool bShow) { m_bShow = bShow; }
void ZOrder(int nZOrder) { m_nZOrder = nZOrder; }
void Theme(string strTheme) { m_strTheme = strTheme; }
void DoUpdate( bool bShow )
{
Show( bShow );
}
void DoUpdate( int nZOrder )
{
ZOrder( nZOrder );
}
void DoUpdate( string strTheme )
{
Theme( strTheme );
}
template<class T>
void UpdateValue(T Value)
{
DoUpdate( Value );
}
int main( int argc, char **argv )
{
string strValue = "Animal";
UpdateValue<string>(strValue);
return 0;
}
答案 3 :(得分:0)
如前所述,UpdateValue<CString>(CString)
实例化失败,因为它无法编译ZOrder(CString)
表达式。请记住,模板实例化只是编译时类型替换,而不是运行时。混合运行时RTTI和模板并不是一个好主意,看起来像模板滥用。
建议使用函数重载而不是模板,它会产生相同的结果:
void UpdateValue(int Value)
{
ZOrder(Value);
}
void UpdateValue(bool Value)
{
BOOL bShow = Value ? TRUE : FALSE;
Show(bShow);
}
void UpdateValue(const CString& Value)
{
Theme(Value);
}
答案 4 :(得分:0)
代码仍在编译中,即使它是死代码。所以在哪里说:
if ( typeid(int) == typeid(Value) )
{
ZOrder(Value);
}
它仍然会尝试编译代码,即使它永远不会执行,因此它会抛出错误。
最好使用模板专业化:
template<class T>
void UpdateValue(T Value) {
// By default, do nothing.
}
void UpdateValue < int >(int value) {
ZOrder(value);
}
void UpdateValue < bool >(bool value) {
BOOL bShow = Value ? TRUE : FALSE;
Show(bShow);
}
void UpdateValue < CString >(CString value) {
Theme(value);
}
这是一个不必要的模板使用,全部告诉。你最好使用几个重载。