简体   繁体   中英

C++ std::function<void()> contained shared_ptr

The project has some callback functions:

using fn = std::function<void()>;

The callback function is a parameter of the class X's constructor:

class X(fn).
X x([](){})
X.fn()

I would like to introduce another type of callback function to indicate id, so I need another type:

using xfn = std::function<void(int)>;

Is there a possible way to change the parameter so that it could support both types of function. The project already contains many code with the first type of function. They are called with X.fn() . I am trying to make class X support X.fn(100) . So people can both call X.fn() and X.fn(100) , with the same name fn. (I don't want it to be a new member with a different name), just like a function with default value. fn() = fn(int val=100)

I want to introduce:

X x([](int x){})
X.fn(100)

Is it possible to change the class constructor to a more general prototype-function like

class X(genereal fn)

so that if class X could receive both [](){} and [](int){} .

You can use templates and std::function to make it accept any type you like, as follows

template<typename ...T>
struct X{

    X(std::function<void(T...)>&& fn_):fn{std::move(fn_)}{}
    std::function<void(T...)> fn;
};
int main()
{
    X<int> x1{[](int x){std::cout << "\n" << x;}};
    x1.fn(3);

    X<> x2{[]( ){std::cout << "\nnon";}};
    x2.fn();
}

Live

Assuming you want to use the same class and allow storing and accessing both functions, you can try the following approach:

#include <functional>
#include <iostream>

struct X
{
  struct Wrapper
  {
    Wrapper(std::function<void(int)> pfn)
      : fn(pfn)
    { }
    Wrapper(std::function<void()> pfn)
      : fn([pfn](int) { pfn(); })
      { }

    void operator()()
    {
      fn(0);
    }

    void operator()(int v)
    {
      fn(v);
    }

    std::function<void(int)> fn;
  };

  X(std::function<void()> pfn)
    : fn(pfn)
  { }
  X(std::function<void(int)> pfn)
    : fn(pfn)
  { }

  Wrapper fn;

};

int main()
{
  X x1([]() { std::cout << "no arg" << std::endl; });
  X x2([](int arg) { std::cout << "int arg = " << arg << std::endl; });
  
  x1.fn();
  x2.fn(100);

  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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