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)
我希望这就是您想要实现的目标:
#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