[英]c++ return template function
我有這種功能:
type uniRndtype()
{
return typeValue;
}
現在我試圖將它們包裝在另一個模板函數中,如下所示:
template<typename T>
T(* uniRndType(void))()
{
if (is_same<T, bool>::value)
{
return uniRndBool;
} else if (is_same<T, char>::value)
{
return uniRndChar;
} else
...
}
並這樣稱呼它:
uniRndType<int>();
但是我遇到一個錯誤: “錯誤:返回值類型與函數類型不匹配”,因為每個返回都具有不同的類型。
我有辦法使其工作嗎? 因為從運行時的角度來看,我看不到任何錯誤,所以只有編譯器才有問題。
問題在於,盡管優化器可以消除無效的代碼分支,但前端(詞法,句法和語義分析)卻無法。 這意味着模板實例中的所有代碼都必須有效。 也就是說,即使在此情況下:
if (is_same<T, bool>::value)
{
return uniRndBool;
}
當T
為char
,body將永遠不會執行,它仍然必須是有效的C ++代碼。 當然不是,因為uniRndBool
沒有正確的類型。
您有兩種選擇:一種在您的特定情況下有效的朴拙的選擇,另一種是通用的。
拙劣的做法是在所有return
語句中使用reinterpret_cast<T(*)()>
。 對於正確的T
分支,將不進行操作。 其他分支永遠不會在運行時執行,因此一切都會好起來的。
另一種解決方案是使用模板專門化。 由於專門設計函數模板不是一個好主意 ,因此可以使用眾所周知的“委托給類”技巧:
template <class T>
struct uniRndTypeHelper;
template <>
struct uniRndTypeHelper<bool>
{
static bool (*get())() { return uniRndBool; }
};
template <>
struct uniRndTypeHelper<char>
{
static char (*get())() { return uniRndChar; }
};
template<typename T>
T(* uniRndType(void))()
{
return uniRndTypeHelper<T>::get();
}
template <typename T> T (*uniRndType())()
{
//else
...
}
template <> bool (*uniRndType())()
{
return uniRndBool;
}
template <> char (*uniRndType())()
{
return uniRndChar;
}
就這樣。
編輯:原則上,我們必須像@Angew。 但是有點麻煩
這是行不通的,因為當編譯器將模板方法擴展為給定類型時,該方法必須有效。 您的類型T必須與列出的所有返回類型兼容,例如bool
, char
等。正如我在評論中所提到的,如果您傳入了std::string
您不會期望該方法起作用,您?
解決此問題的一種方法是使用模板特化指示每種類型的需求。
編譯器需要知道在編譯時函數/方法將使用哪種類型。 此時,您必須使用可以作為模板參數接收的類型實例化此模板函數,例如@ikh在此處編寫的。
但是,如果將模板類與模板方法一起使用,則有兩種方法:
1)只需將每個模板方法的實現寫在.h文件中(就在聲明模板類主體的位置),而不是僅使用原型;
2)或在.h文件中聲明原型后,您需要使用可能會收到的模板參數來實例化此模板類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.