2017-10-05 163 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