C 函数调用包装器包含类成员功能作为模板参数

C++ function call wrapper with class member function as template argument

本文关键字:参数 功能 成员 函数调用 包装 包含类      更新时间:2023-10-16

我尝试使用此代码,但它与类成员功能不起作用。有没有一种方法可以生成类成员功能的包装器,并将其称为非班级成员的包装器?

#include <functional>
template <typename F>
class wrapper;
template <typename F, typename... Args>
typename std::result_of<F(Args...)>::type execute_helper (F&& f, Args&&... args) {
    return std::forward<F>(f)( std::forward<Args>(args)...);
}
template<typename Ret, typename... Args>
class wrapper <std::function<Ret(Args...)>>
{
    std::function<Ret(Args...)> m_f;
public:
    wrapper( std::function<Ret(Args...)> f ): m_f(f) {}
    Ret operator()(Args... args) const  { 
        return execute_helper (m_f, args...); 
    }
};

成员函数的问题是他们需要一个名为类的对象。

假设您可以将类的对象以及指向成员函数的指针传递给构造函数,我想您可以按照以下方式编写包装器

template <typename Ret, typename Cl, typename ...Args>
class wrapper <Ret(Cl::*)(Args...)>
 {
   private:
      std::function<Ret(Args...)> m_f;
   public:
      wrapper (Cl cl, Ret(Cl::*m)(Args...))
         : m_f{ [=](Args... as) mutable { return (cl.*m)(as...); } }
          { }
      Ret operator() (Args... args) const
       { return m_f(args...); }
 };

以下是使用的完整汇编示例

#include <functional>
#include <iostream>
template <typename F>
class wrapper;
template <typename Ret, typename Cl, typename ...Args>
class wrapper <Ret(Cl::*)(Args...)>
 {
   private:
      std::function<Ret(Args...)> m_f;
   public:
      wrapper (Cl cl, Ret(Cl::*m)(Args...))
         : m_f{ [=](Args... as) mutable { return (cl.*m)(as...); } }
          { }
      Ret operator() (Args... args) const
       { return m_f(args...); }
 };
struct foo
 {
   long long bar (int a, long b, long long c)
    { return a+b+c; }
 };
int main ()
 {
   foo  f;
   wrapper<decltype(&foo::bar)>  wfb{f, &foo::bar};
   std::cout << wfb(1, 2l, 3ll) << std::endl;
 }

观察该示例适用于非const成员函数。

对于const成员函数,您可能需要另一个包装器

template <typename Ret, typename Cl, typename ...Args>
class wrapper <Ret(Cl::*)(Args...) const>
 {
   private:
      std::function<Ret(Args...)> m_f;
   public:
      wrapper (Cl const & cl, Ret(Cl::*m)(Args...) const)
         : m_f{ [=](Args... as) { return (cl.*m)(as...); } }
          { }
      Ret operator() (Args... args) const
       { return m_f(args...); }
 };

在这两种情况下,您都可以提高 operator()添加完美转发

  template <typename ... As>   
  Ret operator() (As && ... as) const
   { return m_f(std::forward<As>(as)...); }