代码之家  ›  专栏  ›  技术社区  ›  Yucel_K

如何使std::函数和lambda可以接受任何类型的参数

  •  2
  • Yucel_K  · 技术社区  · 7 年前

    我有一个名为Foo的类,它包含一个std::function成员,该成员绑定到我要调用的函数。

    什么时候? Foo::DoCallback

    接受带有int类型参数的std::函数的构造函数。
    Foo(std::function<void(int)> callback, int a)



    Foo(std::function<void(bool)> callback, bool condition)

    和默认构造函数,它不接受任何参数。

    Foo(std::function<void()> callback = nullptr) : Callback(callback)

    每个lambda接受不同类型的参数,并将它们作为参数传递给将用作回调的函数。

      auto lambdaA = [](int a)
      {
        FunctionA(a);
      };
    
      auto lambdaB = [](bool condition)
      {
        FunctionB(condition);
      };
    
      auto lambdaC = []()
      {
        FunctionC();
      };
    

    • 创建Foo unique ptr时需要作为参数传递的lambda。
    • 一个foo构造函数,它接受新类型的std::function参数,并接受其他类型的参数。


    这是完整的代码

    --主要--

    #include <iostream>
    #include <string>
    #include <memory>
    #include "Foo.h"
    void FunctionA(int a)
    {
      std::cout << "FunctionA called. param 1 = " << std::to_string(a) << "\n";
    }
    
    void FunctionB(bool condition)
    {
      std::cout << "FunctionB called. param 1 = " << std::to_string(condition) << "\n";
    }
    
    void FunctionC()
    {
      std::cout << "FunctionC called with no params" << "\n";
    }
    int main()
    {
      auto lambdaA = [](int a)
      {
        FunctionA(a);
      };
    
      auto lambdaB = [](bool condition)
      {
        FunctionB(condition);
      };
    
      auto lambdaC = []()
      {
        FunctionC();
      };
    
      std::unique_ptr<Foo> FooPtrA = std::make_unique<Foo>(lambdaA,10);
      std::unique_ptr<Foo> FooPtrB = std::make_unique<Foo>(lambdaB ,false);
      std::unique_ptr<Foo> FooPtrC = std::make_unique<Foo>(lambdaC);
    
      FooPtrA->DoCallback();
      FooPtrB->DoCallback();
      FooPtrC->DoCallback();
    
      return 0;
    }
    

    --Foo.h公司

    #pragma once
    #include <functional>
    class Foo
    {
    public:
      //constructor with a parameter callback which could take an int parameter
      Foo(std::function<void(int)> callback, int a) 
      {
        Callback = std::bind(callback, a);
      }
      //constructor with a parameter callback which could take a bool parameter
      Foo(std::function<void(bool)> callback, bool condition)
      {
        Callback = std::bind(callback, condition);
      }
    
      //constructor with a parameter callback which takes no parameter
      Foo(std::function<void()> callback = nullptr) : Callback(callback)
      {
      }
    
      void DoCallback()
      {
        Callback(); //calling the callback function that is binded
      }
    private:
      std::function<void()> Callback;
    };
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Eric    7 年前

    比箭鱼的答案更进一步,您可以消除 std::function 通过使用任何类型参数化:

    template<typename F, typename T>
    Foo(F f, T a)
        : Callback{ std::bind(f, a) } } {}
    

    如果您想让它适用于任意数量的参数,并正确调用move构造函数:

    template<typename F, typename... Args>
    Foo(F&& f, Args&&... a)
        : Callback{ std::bind(std::forward<F>(f), std::forward<Args>(a)...) } {}
    
        2
  •  1
  •   Swordfish    7 年前

    使用模板?

    template<typename T>
    Foo(std::function<void(T)> callback, T a) : Callback{ std::bind(callback, a); }
    {}
    
    推荐文章