简体   繁体   English

如何编写带有模板化函数参数的包装函数,该函数可以采用重载成员函数?

[英]How do I write a wrapper function with templated function parameters which can take overloaded member functions?

I'm working with a legacy codebase which uses a bunch of callbacks to member functions. 我正在使用旧版代码库,该代码库使用一堆成员函数的回调。 As part of a refactoring effort, I'm attempting to wrap these callback calls. 作为重构工作的一部分,我正在尝试包装这些回调调用。

My current implementation is attempting to use a variadic template function to replace/wrap the bind call. 我当前的实现方式是尝试使用可变参数模板函数替换/包装绑定调用。

template< typename F, typename T, typename... Args >
auto
my_bind(F fxn, T * obj, Args&&... args)
    -> decltype( boost::bind( fxn, obj, std::forward<Args>(args)... ) )
{
    return boost::bind( fxn, obj, std::forward<Args>(args)... );
}

(The actual implementation will add wrapper classes around the fxn & obj objects, but I removed that to give a minimal example which still shows the issue.) (实际的实现将在fxn和obj对象周围添加包装器类,但我删除了包装器类,以提供一个仍然显示问题的最小示例。)

This mostly works, but fails where the fxn object is an overloaded member function. 这通常有效,但是在fxn对象是重载成员函数的情况下失败。 In this situation, I'm getting "couldn't deduce template parameter 'F'"/"couldn't infer template argument 'F'" (GCC/Clang) errors. 在这种情况下,我收到“无法推断出模板参数'F'” /“无法推断出模板参数'F'”(GCC / Clang)错误。 This makes a bit of sense, as there's multiple possible functions with different parameter types which could be used. 这有点有意义,因为可以使用具有不同参数类型的多个可能函数。

What's confounding me is that boost::bind is not having issues with the member resolution -- in the original code without the wrapper, I don't see any errors and the binding goes well. 让我感到困惑的是,boost :: bind的成员解析没有问题-在没有包装的原始代码中,我看不到任何错误,并且绑定进展顺利。 Example: 例:

#include <iostream>
#include <boost/bind.hpp> // Boost 1.53

template< typename F, typename T, typename... Args >
auto
my_bind(F fxn, T * obj, Args&&... args)
    -> decltype( boost::bind( fxn, obj, std::forward<Args>(args)... ) )
{
    return boost::bind( fxn, obj, std::forward<Args>(args)... );
}

class Klass {
public:
    void foo( int i ) {
       std::cout << "One param: " << i << "\n";
    }
    void foo( int i, int j ) {
       std::cout << "Two param: " << i << " " << j << "\n";
    }

    void bar( int const & i ) const {
       std::cout << "Bar One param: " << i << "\n";
    }
    int bar( float i, int j ) {
       std::cout << "Bar Two param: " << i << " " << j << "\n";
       return j;
    }
};

int main() {

    Klass k;

    auto f1 = boost::bind( &Klass::foo, &k, 1 );
    f1(); // prints "One param: 1"
    auto f2 = boost::bind( &Klass::foo, &k, 1, 2 );
    f2(); // prints "Two param: 1 2"

    //auto f1a = my_bind( &Klass::foo, &k, 1 ); // Compiler error: couldn't deduce template parameter ‘F’
    //auto f2a = my_bind( &Klass::foo, &k, 1, 2 ); // Compiler error:  couldn't deduce template parameter ‘F’

    double a = 1.1;
    int b = 3;
    //auto b1 = my_bind( &Klass::bar, &k, b ); // Should also work with const functions and const parameters
    //auto b2 = my_bind( &Klass::bar, &k, a, 2 ); // As well as non-void return types and parameter conversions
    // As well as any other member function which the underlying sub-function (here boost::bind) can take.

    return 0;
}

My main question: Given a function (such as, but not necessarily limited to boost::bind ) which is able to appropriately distinguish between different versions of an overloaded member function, is there a way to create a templated wrapper function which can "perfectly forward" the template type from that functions parameter -- that is, is there a way to permit the compiler to make the F type deduction based on the (working) type deduction of the sub-function (eg boost::bind )? 我的主要问题: 给定一个能够适当地区分不同版本的重载成员函数的函数(例如但不一定限于boost::bind ),有没有办法创建一个模板包装器函数,该函数可以“完美地从该函数参数“转发”模板类型-也就是说,是否有一种方法允许编译器根据子函数的(工作)类型推导(例如boost::bind )进行F类型推导?

(I did try replacing the my_bind template function with a variadic preprocessor macro. This fixes the immediate problem, but results in issues later, when I attempt to wrap the fxn object in a templated type. -- I get similar "cannot resolve overloaded function" errors.) (我确实尝试用可变参量的预处理器宏替换my_bind模板函数。这解决了紧迫的问题,但是当我尝试将fxn对象包装为模板类型时,会导致问题fxn我得到类似的“无法解析重载函数“错误。)

I'm targeting C++11, if that makes a difference. 我的目标是C ++ 11,如果有帮助的话。

you may try to force the type of the member function expected like: 您可以尝试强制使用预期的成员函数类型,例如:

#include <iostream>
#include <boost/bind.hpp> // Boost 1.53

template<typename T, typename... Args>
auto
my_bind(void (T::*fxn)(Args...), T * obj, Args&&... args)
    -> decltype( boost::bind( fxn, obj, std::forward<Args>(args)... ) )
{
    return boost::bind( fxn, obj, std::forward<Args>(args)... );
}

class Klass {
public:
    void foo( int i ) {
       std::cout << "One param: " << i << "\n";
    }
    void foo( int i, int j ) {
       std::cout << "Two param: " << i << " " << j << "\n";
    }
};

int main() {

    Klass k;

    auto f1a = my_bind( &Klass::foo, &k, 2 );
    f1a(); // prints One param: 2
    auto f2a = my_bind( &Klass::foo, &k, 2, 3 );
    f2a(); // prints Two param: 2 3

    return 0;
}

暂无
暂无

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

相关问题 boost :: bind&boost ::函数指针指向重载或模板化的成员函数 - boost::bind & boost::function pointers to overloaded or templated member functions 如何区分重载函数的左值和右值成员函数指针? - How do I differentiate an lvalue and rvalue member function pointer for overloaded functions? 重载成员函数的 function 特征 - function traits for overloaded member functions 如何使用cv-qualifier调用重载成员函数? - How do I call overloaded member function with cv-qualifier? 我该如何解决该成员函数问题重载的地址? - How can I resolve this address of overloaded member function issue? 如何解决“找不到重载成员函数”错误? - How can I fix “Overloaded member function not found” error? 当模板化类不包含可用的成员函数时,如何在编译时验证模板参数? - How do I validate template parameters in compile time when a templated class contains no usable member functions? 如何在包装函数之前和之后执行函数和成员函数来编写包装器? - How to write a wrapper over functions and member functions that executes some code before and after the wrapped function? 如何编写由函数模板化的原型转换? - How do I write a proto transform templated by a function? C ++:如何重载函数,使其可以使用任何函子,包括指向成员函数的指针? - C++: how can I overload a function so that it can take any functor, including pointer to member functions?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM