簡體   English   中英

將模板化函數作為 std::function 傳遞並稍后選擇模板參數

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

我正在嘗試構建一個函數tune ,它通過std::function獲取模板化std::function並基於std::integer_sequence初始化一系列該函數。 我不確定這是否可行,我被卡住了。 我做了一個工作示例,展示了我的目標:一個將另一個函數和一個整數列表作為參數的通用函數。 我希望能夠使用底部注釋掉的兩行中的語法,因為使用工作代碼,我必須為每個函數制作一個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;
}

這對於簡單的函數指針或std::function是不可能的(因為它只能指向特定模板的一個實例!)但是您可以做的是將每個函數print_valueprint_value_squared在相應的結構中

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

然后,此結構將模板化實現保存為具有預定義名稱static成員函數,例如impl (遺憾的是,您不能像函子一樣使用operator () ,因為它不允許是static

然后,您的 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>(), ...);
}

在這種情況下,您將需要關鍵字template作為限定符來告訴編譯器成員函數是模板。

然后,您可以調用tune函數,例如

tune<print_value>(is);

在此處使用靜態成員函數impl在此處使用非靜態operator()嘗試

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM