【问题标题】:template function returning template function pointers模板函数返回模板函数指针
【发布时间】:2017-10-05 23:48:21
【问题描述】:

目前我实现了两个模板函数,每个都返回一个使用 boost::variant: 包装的模板函数指针:

  1. 函数fa

    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。

【问题讨论】:

  • 这是什么语言?它看起来不像有效的 C++ 代码。我建议你生成一个minimal reproducible example
  • 如果这与您的实际实现类似,您的第一步是尝试通过编译器运行您已有的内容,并找出将出现的几个错误。

标签: c++ templates boost overloading metaprogramming


【解决方案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&lt;typename&gt; class,所以它可能是F_Tf 的类型参数,它们都是template&lt;template&lt;typename&gt; class&gt;。比较具有函数a =&gt; b 并将其作为参数传递给函数(a =&gt; b) =&gt; c。我们说函数[](int i) { return i + 5; }type int =&gt; int,就像类型template&lt;typename&gt; class Akind * -&gt; *(具体类型到具体类型)。就像高阶函数可以有 (A =&gt; A) =&gt; A 这样的类型,高阶函数可以有像 (* -&gt; *) -&gt; * 这样的类型,例如F_T。像intA_T&lt;A&gt; 这样可以用作变量类型的普通类型有一种*

抛开理论不谈,您可以使用这样的模板模板参数是相当直观的,即使语法起初看起来很奇怪。

【讨论】:

  • 非常有趣,感谢您的回复。顺便说一句,某物代表什么?您是否经常使用模板模板功能(TTF)?使用 TTF 时,我有点担心可读性。我认为编码人员在使用 TTF 时应该添加两倍数量的注释行。不过,我同意 TTF 非常方便。
  • 1) 您不会在 C++ 中大量使用模板模板,因为大多数人不知道它们的存在,从而限制了它们的流行。 2) something 只是伪代码。用一些可以真正创造你需要的价值的代码来代替它。 3)可读性确实是语言的错。如果这是例如Haskell,我只想写:func :: (SomeConstraint f) =&gt; String -&gt; Either (f Int) (f Double)。您可能想要添加一个简短的注释来解释类型参数应该是什么,但是一旦您知道它存在就很容易理解。不要在代码中记录语言特性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-22
  • 1970-01-01
相关资源
最近更新 更多