Forwarding arguments to template member function

点点圈 提交于 2019-12-21 07:34:04

问题


ideone example


I need to forward some predefined arguments plus some user-passed arguments to a member function.

#define FWD(xs) ::std::forward<decltype(xs)>(xs)

template<class T, class... Ts, class... TArgs>
void forwarder(void(T::*fptr)(Ts...), TArgs&&... xs)
{
    T instance;
    (instance.*fptr)(FWD(xs)..., 0);
    //                           ^
    // example predefined argument
}

forwarder(&example::f0, 10, 'a');   
forwarder(&example::f1, 10, "hello", 5);

This works properly for non-template member functions.

The member function pointer passed to forwarder can, however, point to template functions as well. Unfortunately, the compiler is not able to deduce the type of T in that case:

struct example
{
    void f0(int, int) { }

    template<class T>
    void f1(T&&, int) { }
};

// Compiles
forwarder(&example::f0, 10);

// Does not compile
forwarder(&example::f1, 10);

Errors:

prog.cpp:30:28: error: no matching function for call to 'forwarder(<unresolved overloaded function type>, int)'
  forwarder(&example::f1, 10);
                            ^
prog.cpp:20:6: note: candidate: template<class T, class ... Ts, class ... TArgs> void forwarder(void (T::*)(Ts ...), TArgs&& ...)
 void forwarder(void(T::*fptr)(Ts...), TArgs&&... xs)
      ^
prog.cpp:20:6: note:   template argument deduction/substitution failed:
prog.cpp:30:28: note:   couldn't deduce template parameter 'T'
  forwarder(&example::f1, 10);

Is there any way I can help the compiler deduce the correct types without changing the interface of forwarder?

If not, what's the best way of solving this issue without making the user syntax too convoluted?

EDIT: It would also be acceptable to pass the member function pointer as a template parameter, maybe through a wrapper. The target member function will always be known at compile-time. Pseudocode:

forwarder<WRAP<example::f0>>(10, 'a');
// Where WRAP can be a macro or a type alias.

ideone example


回答1:


I compiled your code in gcc 4.9 by providing template arguments to the member function pointer; like this

int main(){
// Compiles
forwarder(&example::f0, 10);
//Does not compile
forwarder(&example::f1, 10);
//Does compile, instantiate template with int or what ever you need
forwarder(&example::f1<int>,10)
}

I believe what is going on is that you need to instantiate the template member function. does that change your interface too much? I think any answer will revolve around instantiating that member template somehow.



来源:https://stackoverflow.com/questions/32016749/forwarding-arguments-to-template-member-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!