簡體   English   中英

C ++返回模板函數

[英]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;
}

Tchar ,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必須與列出的所有返回類型兼容,例如boolchar等。正如我在評論中所提到的,如果您傳入了std::string您不會期望該方法起作用,您?

解決此問題的一種方法是使用模板特化指示每種類型的需求。

編譯器需要知道在編譯時函數/方法將使用哪種類型。 此時,您必須使用可以作為模板參數接收的類型實例化此模板函數,例如@ikh在此處編寫的。

但是,如果將模板類與模板方法一起使用,則有兩種方法:

1)只需將每個模板方法的實現寫在.h文件中(就在聲明模板類主體的位置),而不是僅使用原型;

2)或在.h文件中聲明原型后,您需要使用可能會收到的模板參數來實例化此模板類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM