2017-10-05 289 views
2

目前,我實現了兩個模板函數,每區選出一個模板函數指針使用boost ::包裹變種:模板函數返回模板函數指針

  1. 功能發

    typedef boost::variant<&A<int>,&A<double>> A_T; 
    
    A_T fa(string type) 
    { 
        switch(type){ 
         case "int": return &A<int>; 
         case "double": return &A<double>; 
         default: return &A<int>; 
        } 
    } 
    
  2. 功能FB

    typedef boost::variant<&B<int>,&B<double>> B_T; 
    
    B_T fb(string type) 
    { 
        switch(type){ 
         case "int": return &B<int>; 
         case "double": return &B<double>; 
         default: return &B<int>; 
        } 
    } 
    

我的問題是「我們可以將兩個函數合併爲一個模板函數,它將A或B的函子指針作爲模板參數嗎?」。爲什麼我需要這個的原因是因爲我可以有兩個以上的函子像A和B.

+3

這是什麼語言?它看起來不像有效的C++代碼。我建議你生成一個[mcve] –

+0

如果這與你的實際實現類似,你的第一步就是嘗試運行你已經通過編譯器得到的東西,並找出出現的幾個錯誤。 – aschepler

回答

1

簡單:

template<template<typename> class F> // template template 
using F_T = boost::variant<F<int>&, F<double>&>; // Need C++11 for this (not strictly needed) alias 

template<template<typename> class F> 
F_T<F> f(std::string type) { 
    if(type == "double") return something<F<double>&>(); 
    else return something<F<int>&>(); 
} 

using A_T = F_T<A>; 
A_T at = f<A>("int"); 
// F_T<int> broken; // invalid: int is not a template<typename> class 
// f<int>("int") // invalid: int is not a template<typename> class 

Atemplate<typename> class,所以它可能是類型參數F_Tf,其中都是template<template<typename> class>。比較一個函數a => b並將它作爲參數傳遞給函數(a => b) => c。我們說一個功能[](int i) { return i + 5; }類型int => int,就像一個類型template<typename> class A* -> *(混凝土類型爲混凝土類型)。就像更高階函數可以具有類型如(A => A) => A一樣,更高階的類型可以具有類似(* -> *) -> *的類型,例如, F_T。正常類型如intA_T<A>可用作變量類型,種類爲*

除了理論之外,很直觀的是,您可以擁有像這樣的模板模板參數,即使語法一開始看起來很亂。

+0

非常有趣,謝謝你的回覆。順便說一句,什麼東西代表? 您是否經常使用模板模板功能(TTF)?使用TTF時,我有點擔心可讀性。我認爲編碼員在使用TTF時應該添加兩倍的註釋行。不過,我同意TTF非常方便。 –

+0

1)你不會在C++中使用模板模板,因爲大多數人不知道它們存在,限制了它們的流行。 2)'something'只是僞代碼。用一些可以實際創建所需值的代碼替換它。 3)可讀性實際上是語言的錯誤。如果這是例如Haskell,我只寫:'func ::(SomeConstraint f)=> String - >或者(f Int)(f Double)'。您可能需要添加一段簡短的註釋,說明類型參數應該是什麼,但一旦知道它存在就很容易理解。不要在代碼中記錄語言功能。 – HTNW