简体   繁体   English

如何为其他类成员函数编写模板包装器方法?

[英]How to write a template wrapper method for other class member functions?

I try to create a templated wrapper for different functions with different parameters. 我尝试使用不同的参数为不同的函数创建模板化包装器。 The setup is a class A with the basic implementation of two methods foo and bar . 设置是A类,基本实现了两个方法foobar Another class B shall wrap these methods and add new functionality. 另一个B类应包装这些方法并添加新功能。

The solution from the following link works very well for non-class functions: c++11: Templated wrapper function 以下链接的解决方案非常适用于非类函数: c ++ 11:模板化包装函数

But if I try to invoke methods from another class I get an error. 但是如果我尝试从另一个类调用方法,我会收到错误。

#include <algorithm>
#include <functional>
#include <iostream>

class A
{
public:
    void foo(int x) {
        std::cout << "Foo: " << x << std::endl;
    }

    void bar(int x, float y) {
        std::cout << "Bar: " << x << ", " << y << std::endl;
    }
};

class B
{
public:
    void fooAndMore(int x) {
        foobarWrapper(&A::foo, 1);
    }

    void barAndMore(int x, float y) {
        foobarWrapper(&A::bar, 1, 3.5f);
    }

    template<typename  T, typename... Args>
    void foobarWrapper(T&& func, Args&&... args)
    {
        std::cout << "Start!" << std::endl;
        std::forward<T>(func)(std::forward<Args>(args)...);
        std::cout << "End!" << std::endl;
    }
};

int main()
{
    B b;
    b.fooAndMore(1);
    b.barAndMore(2, 3.5f);
}

I expect something like that: 我期待这样的事情:

Start!
Foo: 1
End!
Start!
Bar: 1, 3.5
End!

But instead I get: 但相反,我得到:

error C2064: term does not evaluate to a function taking 1 arguments
note: see reference to function template instantiation 'void B::foobarWrapper<void(__thiscall A::* )(int),int>(T &&,int &&)' being compiled
    with
    [
        T=void (__thiscall A::* )(int)
    ]

error C2064: term does not evaluate to a function taking 2 arguments
note: see reference to function template instantiation 'void B::foobarWrapper<void(__thiscall A::* )(int,float),int,float>(T &&,int &&,float &&)' being compiled
    with
    [
        T=void (__thiscall A::* )(int,float)
    ]

Any idea how to solve this? 不知道怎么解决这个问题?

The simplest fix is to make the member functions of class A to be static . 最简单的解决方法是使A类的成员函数是static ( See online ) 见在线

class A
{
public:
    static void foo(int x) {
    ^^^^^^
        std::cout << "Foo: " << x << std::endl;
    }

    static void bar(int x, float y) {
    ^^^^^^
        std::cout << "Bar: " << x << ", " << y << std::endl;
    }
};

Otherwise, you need to pass an instance of class A to call its member functions in the foobarWrapper function. 否则,您需要传递A类的实例以在foobarWrapper函数中调用其成员函数。 Using lambdas you can pack them to the callable func and pass to the foobarWrapper . 使用lambdas,您可以将它们打包到可调用的func并传递给foobarWrapper

( See online ) 见在线

class B
{
public:
    void fooAndMore(const A& a_obj, int x) {
        foobarWrapper([&]() { return a_obj.foo(x); });
        //            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Args captured to the lambda
    }

    void barAndMore(const A& a_obj, int x, float y) {
        foobarWrapper([&]() { return a_obj.bar(x, y); });
        //            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  Args captured to the lambda
    }

    template<typename  T>
    void foobarWrapper(T&& func)   // no Args needed any more (@credits Jarod42)
    {
        std::cout << "Start!" << std::endl;
        std::forward<T>(func)();   // simply call the func
        std::cout << "End!" << std::endl;
    }
};

int main()
{
    B b;
    b.fooAndMore(A{}, 1);       // pass a temporary A object
    b.barAndMore(A{}, 2, 3.5f);
}

Try this, 试试这个,

#include <algorithm>
#include <functional>
#include <iostream>

class A
{
public:
    void foo(int x) {
        std::cout << "Foo: " << x << std::endl;
    }

    void bar(int x, float y) {
        std::cout << "Bar: " << x << ", " << y << std::endl;
    }
};

class B
{
public:
    void fooAndMore(int x) {
        foobarWrapper(&A::foo, x);
    }

    void barAndMore(int x, float y) {
        foobarWrapper(&A::bar, x, y);
    }

    template<typename  T, typename... Args>
    void foobarWrapper(T func, Args&&... args)
    {
        std::cout << "Start!" << std::endl;

        auto caller = std::mem_fn( func); // Newly added lines
        caller( A(), args...);  // Newly added line

        std::cout << "End!" << std::endl;
    }
};

int main()
{
    B b;
    b.fooAndMore(1);
    b.barAndMore(2, 3.5f);
}

output: 输出:

Start!
Foo: 1
End!
Start!
Bar: 2, 3.5
End!

See this link for more details std::mem_fn 有关详细信息,请参阅此链接std :: mem_fn

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

相关问题 如何在模板类中专门化模板成员函数? - how to specialize template member functions in template class? c ++模板类的成员函数,依赖于其他模板类 - c++ Template Class member functions, reliance on other template classes 如何编写一个C ++类成员函数包装器? - how to write a C++ class member function wrapper? 如何围绕任意成员函数编写通用非成员包装器? - How to write a generic non-member wrapper around arbitrary member functions? 如何在包装函数之前和之后执行函数和成员函数来编写包装器? - How to write a wrapper over functions and member functions that executes some code before and after the wrapped function? 类模板的外部成员函数 - External member functions of class template 隐藏模板类中的成员函数 - Hiding member functions in a template class 具有无效成员函数的模板类 - Template class with invalid member functions 如何编写带有模板化函数参数的包装函数,该函数可以采用重载成员函数? - How do I write a wrapper function with templated function parameters which can take overloaded member functions? 任意类的const和非const成员函数的模板包装器 - Template wrapper for const and non const member functions of arbitrary classes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM