简体   繁体   English

指向可变参数函数模板的指针

[英]Pointer to variadic function template

I have a simple class A , providing a variadic function template. 我有一个简单的类A ,提供可变参数函数模板。 This function uses private data from within A , but the function itself is public. 此函数使用A私有数据,但函数本身是公共的。 The class goes as follows: 课程如下:

class A {
public:

    A() :
    _bla("bla: ") {
    }

    template <class T>
    void bar(const T& value) {
        std::cout << _bla << value << std::endl;
    }

    template <class H, class... T>
    void bar(const H& value, const T&... data) {
        std::cout << _bla << value << std::endl;
        bar(data...);
    }

private:
    const std::string _bla;
};

In a separate file, named foo.hpp , I have a function foo() , that should be able to receive and use the function a.bar() as an argument: 在一个名为foo.hpp的单独文件中,我有一个函数foo() ,它应该能够接收并使用函数a.bar()作为参数:

int main(int argc, char *argv[]) {    
    A a;
    a.bar(1, "two", 3, 4);
    foo(&a.bar);
}

I'm not very sure of where to start, but I've tried the following -- which does not work. 我不太确定从哪里开始,但我尝试了以下 - 这不起作用。 How can I do it correctly: 我该怎么做才能正确:

template <typename... T>
inline void foo(void (bar *)(const T&...)) {
    unsigned int x(0), y(0), z(0);
    bar(x, y, z);
}

Bonus question: is there a way to call not only: 奖金问题:有没有办法打电话:

foo(&a.bar);

but also call foo with a.bar bound to some parameters, like: 但也可以使用绑定到某些参数的a.bar调用foo ,例如:

foo(&(a.bar(p1, p2));

I can simply add p1 and p2 to foo definition itself, like in: 我可以简单地将p1p2添加到foo定义本身,如:

foo(p1, p2, &a.bar);

but it would be semantically better to my purpose if I could add these parameters before. 但如果我之前可以添加这些参数,那么在语义上会更好。

You cannot pass the address of a function template without instantiating it, because that is treated as a whole overload set (no matter whether the template is variadic or not). 您无法在不实例化的情况下传递函数模板的地址,因为它被视为整个重载集(无论模板是否为可变参数)。 You can, however, wrap it in a generic functor: 但是,您可以将其包装在通用仿函数中:

struct bar_caller
{
    template<typename... Ts>
    void operator () (A& a, Ts&&... args)
    {
        a.bar(std::forward<Ts>(args)...);
    }
};

And then let your function foo() be defined as follows: 然后让你的函数foo()定义如下:

template<typename F>
inline void foo(A& a, F f) {
    unsigned int x(0), y(0), z(0);
    f(a, x, y, z);
}

So your function call in main() would become: 所以你在main()函数调用将变为:

int main()
{
    A a;
    a.bar(1, "two", 3, 4);
    foo(a, bar_caller());
}

Unfortunately, at the moment there is no way in C++ to easily wrap an overload set in a functor without defining a separate class - as done above for bar_caller . 不幸的是,目前在C ++中没有办法在没有定义单独的类的情况下轻松地在函子中包装重载集 - 如上面针对bar_caller所做的bar_caller

EDIT: 编辑:

If you do not want to pass an A object directly to foo() , you can still let your bar_caller encapsulate a reference to the A object on which the function bar() has to be called (just take care of object lifetime, so that you won't be making that reference dangling): 如果您不想将A对象直接传递给foo() ,您仍然可以让bar_caller封装对必须调用函数bar()A对象的引用(只需处理对象生存期,以便你不会晃来晃去参考):

struct bar_caller
{
    bar_caller(A& a_) : a(a_) { }

    template<typename... Ts>
    void operator () (Ts&&... args)
    {
        a.bar(std::forward<Ts>(args)...);
    }

    A& a;
};

You could then rewrite foo() and main() as follows: 然后你可以重写foo()main() ,如下所示:

template<typename F>
inline void foo(F f) {
    unsigned int x(0), y(0), z(0);
    f(x, y, z);
}

int main()
{
    A a;
    a.bar(1, "two", 3, 4);
    foo(bar_caller(a));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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