[英]Variadic Template Parameter Expansion Inside Class member of Type std::function
我有一個名為“菜單”的類,用於顯示用戶可以選擇的選項。 然后用戶選擇一個選項並處理該值。 但是,我有一個不顯示任何內容的子類,而是只接收一個帶有可變數量參數的 std::function 。
簽名看起來像
template<class FuncRetTy, class... FuncArgs>
class FunctionMenu : public Menu;
理想情況下,我想保存一個具有以下形式的類成員:
std::function<FuncRetTy(FuncArgs...)> m_function;
我還想從構造函數中自動推導出所有類型並保存FuncArgs...
的值FuncArgs...
這樣每次調用重寫的“ run()
”方法時,這些值都可以通過此函數run()
。 在run()
, m_function(/* FuncArgs values */)
將被調用。
歡迎任何想法。 我正在使用帶有 C++17 的 Visual Studio 2019。
這是你想要的嗎?
#include <functional>
#include <iostream>
template<class Ret, class... Args>
class FunctionMenu {
std::function<Ret(Args...)> m_function;
public:
FunctionMenu(std::function<Ret(Args...)> f) : m_function(f) {}
Ret run(Args... args) {
return f(args...);
}
};
template<class Ret, class... Args>
FunctionMenu(std::function<Ret(Args...)>)->FunctionMenu<Ret, Args...>;
int test(int i, double d) {
std::cout << i << ' ' << d << '\n';
return 0;
}
int main() {
std::function m = test;
FunctionMenu fm{m};
}
(我沒有添加 Menu 基類,因為它似乎不相關)
最簡單的方法是使用std::bind
來存儲參數。
#include <functional>
template <typename Ret>
class FunctionMenu {
public:
template <typename Ret, typename... Args>
explicit FunctionMenu(std::function<Ret(Args...)> func, Args... args)
: m_function{std::bind(func, std::move(args)...)} {}
auto run() { return m_function(); }
private:
std::function<Ret()> m_function;
};
template <typename Ret, typename... Args>
FunctionMenu(std::function<Ret(Args...)>, Args...)->FunctionMenu<Ret>;
這樣,參數存儲在std::function
。 也可以將參數手動存儲在std::tuple
,並在調用run()
時run()
它們解包。
#include <tuple>
template <typename Ret, typename... Args>
class FunctionMenu2 {
public:
template <typename Ret, typename... Args>
explicit FunctionMenu2(std::function<Ret(Args...)> func, Args... args)
: m_function{func}, m_args{std::move(args)...} {}
auto run() { return std::apply(m_function, m_args); }
private:
std::function<Ret(Args...)> m_function;
std::tuple<Args...> m_args;
};
template <typename Ret, typename... Args>
FunctionMenu2(std::function<Ret(Args...)>, Args...)
->FunctionMenu2<Ret, Args...>;
第二種方法允許您更輕松地訪問參數(如果需要)。 這是使用這兩個類的方法:
int main() {
std::function<int(float, int)> f = [](auto a, auto b) {
std::cout << a << std::endl;
std::cout << b << std::endl;
return 0;
};
FunctionMenu menu(f, 1.f, 200);
FunctionMenu2 menu2(f, 1.f, 200);
std::cout << menu.run() << std::endl;
std::cout << menu2.run() << std::endl;
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.