【问题标题】:Convert function template into templated functor将函数模板转换为模板化函子
【发布时间】:2019-08-07 12:28:08
【问题描述】:

我想知道是否可以从函数模板创建函数对象。以下Functor 结构从函数创建函数对象:

#include <iostream>

template <typename F, F* f>
struct Functor {
  template <typename... Ar>
  auto operator()(Ar&&... rg) -> decltype(f(std::forward<Ar>(rg)...)) {
    return f(std::forward<Ar>(rg)...);
  }
};

int plus_one(int a) {
  return a + 1;
}

int main () {

  std::cout << Functor<decltype(plus_one), &plus_one>()(1) << "\n";

  return 0;
}

这会创建一个类似的结构

struct PlusOne {
  int operator()(int a) {
    return a + 1;
  }
}

现在,我想使用函数模板而不是函数:

template <typename T>
T plus_one(T a) {
  return a + 1;
}

我希望变成这样的东西

struct PlusOne {
  template <class T>
  T operator()(T a) {
    return a + 1;
  }
};

这可能吗?我问这个的原因之一是我 read C++14 中的通用 lambda 表达式正在变成类似于我所追求的仿函数:

例如,这个包含通用 lambda 表达式的语句:

 auto L = [](const auto& x, auto& y){ return x + y; };

可能会导致创建闭包类型,以及行为类似于以下结构的对象:

struct {
  template <typename T, typename U>
  auto operator()(const T& x, U& y) const { return x + y; }
} L;

所以我天真地希望有一些设施可以使我所追求的成为可能。不过我仅限于 C++11。

【问题讨论】:

    标签: c++ c++11 functor


    【解决方案1】:

    不,这是不可能的。模板名称本身的使用方式非常有限。在传递它之前,您必须将它包装在一个类中。在 C++14 中,使用 lambda 封装对函数的调用似乎是最简单的方法。然后你可以通过多种方式使用它:

    auto wrapper = [](const auto& x){ return plus_one(x); }
    
    std::cout << wrapper(42) << "\n";
    std::cout << std::invoke(wrapper, 42) << "\n";
    std::cout << std::bind(wrapper, 42)() << "\n";
    // etc.
    

    在 C++11 中,我们有点搞砸了。我们必须自己编写包装器:

    struct Wrapper {
        template <typename T>
        auto operator()(const T& x) const
        {
            return plus_one(x);
        }
    };
    

    然后

    Wrapper wrapper;
    // same usage
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-28
      • 2022-01-04
      • 1970-01-01
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 2017-12-24
      • 1970-01-01
      相关资源
      最近更新 更多