绑定成员以可变方式运行

luc*_*nte 12 c++ templates variadic-templates c++11 std-function

我有一个带有可变数量参数的成员函数,存储在a中std::function,我希望绑定实例并获得一个独立的函数对象.

template <class T, class R, class... Args>
void connect(const T& t, std::function<R(const T&, Args...)> f) {
  std::function<R(Args...)> = /* bind the instance c into the function? */
}

// ...

Class c;
connect(c, &Class::foo);
Run Code Online (Sandbox Code Playgroud)

对于我使用的固定数量的参数std::bind,但我不知道如何为可变参数执行此操作.

Xeo*_*Xeo 15

解决方案非常简单,因为您已经拥有大量的参数和所有内容:

template <class T, class R, class... Args>
void connect(const T& t, std::function<R(const T&, Args...)> f) {
  // or capture 't' by-value
  std::function<R(Args...)> fun = [&t,f](Args... args){ f(t,args...); };
  // ...
}
Run Code Online (Sandbox Code Playgroud)

实例.

  • @lucas:即使是聪明的完美转发魔法也不会神奇地使通过`std :: function`的调用消失.;) (4认同)
  • @lucas:如果你不想要不需要的副本,最好将`std :: function`参数指定为引用.;) (2认同)

Bro*_*thy 1

我希望这就是您想要实现的目标:

#include <iostream>
#include <cstdarg>
#include <functional>

class Class {
  public:
    void foo(...)
    {
        std::cout << "foo" << std::endl;
    } 
};

template <typename RES_T>
using ClassVarMemFunT = RES_T (Class::*)(...);

// Without typedef:
// template <class... ARGS, class CLASS_T, class RES_T>
// std::function<RES_T(ARGS...)> connect(CLASS_T& object, RES_T (CLASS_T::*funPtr)(...)) 

template <typename... ARGS, typename CLASS_T, typename RES_T>
std::function<RES_T(ARGS...)> connect(CLASS_T& object, ClassVarMemFunT<RES_T> funPtr)
{
    std::function<RES_T(ARGS...)> resultFun = [&object, funPtr](ARGS&&... args) -> RES_T { 
        return (object.*funPtr)(std::forward<ARGS>(args)...);
    };
    return resultFun;
}

int main() {
    Class c;
    auto funPtr1 = connect<int, float>(c, &Class::foo);
    funPtr1(10, 2.f);

    auto funPtr2 = connect<double, float, int>(c, &Class::foo);
    funPtr2(2., 2.f, 10);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在我的实现中,connect期望实际参数类型作为模板参数。该connect函数返回一个std::function需要具有ARGS...类型的参数的 an 。

connect 有两个参数:

  • 一个用于具有可变参数函数 ( ) 的对象object
  • 一个用于指向我们要调用的可变参数函数的成员函数指针 ( funPtr)。

std::bind我们不能在实现中使用(我们可以,但它会涉及大量的样板文件来std::placeholders根据需要添加尽可能多的代码ARGS)。

因此,我引入了一个 lambda,它需要实际的ARGS类型化参数。我们可以将 lambda 作为 an 返回std::function,然后就可以开始了。

https://godbolt.org/z/7cx3rcYh8

我创建了一个也可以打印可变参数列表的版本:

https://godbolt.org/z/nMxj7Wh9j