簡體   English   中英

類型 std::function 的類成員內部的可變模板參數擴展

[英]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.

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