简体   繁体   English

将模板化函数作为 std::function 传递并稍后选择模板参数

[英]Pass templated function as a std::function and choose template argument later

I am trying to construct a function tune that takes a templated function via std::function and initializes a series of that function based on a std::integer_sequence .我正在尝试构建一个函数tune ,它通过std::function获取模板化std::function并基于std::integer_sequence初始化一系列该函数。 I am not sure whether this is possible, and I am stuck.我不确定这是否可行,我被卡住了。 I made a working example that shows what I aim to achieve: a generic function that takes another function and an integer list as an argument.我做了一个工作示例,展示了我的目标:一个将另一个函数和一个整数列表作为参数的通用函数。 I would like to be able to use the syntax that is in the two lines commented out in the bottom, because with the working code, I have to make a tune function for each function.我希望能够使用底部注释掉的两行中的语法,因为使用工作代码,我必须为每个函数制作一个tune函数。

#include <iostream>
#include <functional>

template<int I> void print_value() { std::cout << I << std::endl; }
template<int I> void print_value_squared() { std::cout << I*I << std::endl; }

template<int... Is>
void tune_print_value(std::integer_sequence<int, Is...>)
{
    (print_value<Is>(), ...);
}

/* NOT SURE HOW TO DO THIS...
template<class Func&&, int... Is>
void tune(std::function<Func> f, std::integer_sequence<int, Is...)
{
    (f<Is>(), ...);
}
*/

int main()
{
    std::integer_sequence<int, 1, 2, 3> is;
    tune_print_value(is);

    // I would like:
    // tune(print_value, is);
    // tune(print_value_squared, is);

    return 0;
}

This is not possible with a simple function pointer or std::function (as it can only point to one instance of a particular template!) but what you can do though is to wrap each function print_value or print_value_squared in a corresponding struct这对于简单的函数指针或std::function是不可能的(因为它只能指向特定模板的一个实例!)但是您可以做的是将每个函数print_valueprint_value_squared在相应的结构中

struct print_value {  
  template <int I>
  static constexpr int impl() {
    std::cout << I << std::endl;
    return I;
  }
};

This struct then holds the templated implementation as a static member function with a predefined name such as impl (sadly you can't use operator () like for a functor as it is not allowed to be static )然后,此结构将模板化实现保存为具有预定义名称static成员函数,例如impl (遗憾的是,您不能像函子一样使用operator () ,因为它不允许是static

Your tune function then takes this struct as a template argument and "magically" (in C++20 you could create a concept for this as follows , prior to it you might use SFINAE and std::enable_if as follows ) accesses the wrapped template function impl .然后,您的 tune 函数将该struct作为模板参数并“神奇地”(在 C++20 中,您可以为此创建一个概念,如下所示,在此之前您可以使用 SFINAE 和std::enable_if如下)访问包装的模板函数impl

template<class Func, int... Is>
auto tune(std::integer_sequence<int, Is...>) {
  return (Func::template impl<Is>(), ...);
}

You will need the keyword template as a qualifier in this case to tell the compiler that the member function is a template.在这种情况下,您将需要关键字template作为限定符来告诉编译器成员函数是模板。

You can then call the tune function like然后,您可以调用tune函数,例如

tune<print_value>(is);

Try it here with a static member function impl or here with a non-static operator() .在此处使用静态成员函数impl在此处使用非静态operator()尝试

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM