尝试使用参数包绑定std :: function时获取未声明的args

时间:2017-11-16 18:11:20

标签: c++ c++11 templates variadic-templates variadic-functions

我正在尝试创建一个如下所示的可变参数模板类:

template <class... Args>
class Message
{
    private:

        std::function<void(Args...)> _function;
    public:
    //stuff

};

我希望有一个绑定选项,这样用户可以在需要时绑定任何函数(带有相应的参数)。我尝试过这种方法(这个函数是Message类的一部分,所以Args...来自类的模板参数):

    template<class T>
    void Message::bindFunction(void(T::*function)(Args... args), T* ownerPtr)
    {
        //This doesn't work
        _function = boost::bind(function,args, ownerPtr);
    }

但是上面的方法不起作用,我试图从bind函数中的args创建元组,但是编译器一直在说:

<args_0> undeclared identifier.

(如果我传递更多参数,则更改)

从用户的角度来看,它应该如下所示:

class Foo
{
public:

    void test2(int a, float b, double c) 
    {  
        std::cout << "bla";
    }
};

int main()
{
    Foo f;

    Message<int,float,double> Mess;

    Mess.bindFunction(&Foo::test2, &f);
}

我看过很多关于转发参数的文章,但是大多数答案比我已经使用不同的模板结构而不解释它们更让我困惑。

1 个答案:

答案 0 :(得分:2)

使用lambda因为它们更好(Live Demo (C++11)):

template<class T>
void bindFunction(void(T::*function)(Args...), T* ownerPtr)
{
    _function = [function, ownerPtr](Args... args)
    {
        (ownerPtr->*function)(args...);
    };
}

我们正在lambda声明中捕获带有[function, ownerPtr]的类实例的函数指针和指针。

lambda接受一个参数列表,其类型在Message类的可变参数模板中指定:Args... args

在内部,我们使用带有(ownerPtr->*function)语法的实例调用函数,然后通过展开参数包(args...)

传递参数

要调用该函数,您可以编写如下内容:

void callFunction(Args&&... args)
{
    _function(std::forward<Args>(args)...);
}

我们使用perfect forwarding将我们的参数传递给std::function<void(Args...)>成员。