将参数转发给模板成员函数
Forwarding arguments to template 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);
这适用于非模板成员函数。
但是,传递给 forwarder
的成员函数指针也可以指向模板函数。不幸的是,在这种情况下,编译器无法推断出 T
的类型:
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);
错误:
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);
有什么方法可以帮助编译器推断出正确的类型 而不更改 forwarder
的接口?
如果不是,在不使用户语法过于复杂的情况下解决此问题的最佳方法是什么?
编辑: 将成员函数指针作为模板参数传递也是可以接受的,也许通过包装器。目标成员函数在编译时总是已知的。伪代码:
forwarder<WRAP<example::f0>>(10, 'a');
// Where WRAP can be a macro or a type alias.
我通过向成员函数指针提供模板参数在 gcc 4.9 中编译了您的代码;
像这样
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)
}
我相信您需要实例化模板成员函数。
这会改变你的界面吗?
我认为任何答案都将围绕以某种方式实例化该成员模板为中心。
我需要将一些预定义的参数和一些用户传递的参数转发给成员函数。
#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);
这适用于非模板成员函数。
但是,传递给 forwarder
的成员函数指针也可以指向模板函数。不幸的是,在这种情况下,编译器无法推断出 T
的类型:
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);
错误:
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);
有什么方法可以帮助编译器推断出正确的类型 而不更改 forwarder
的接口?
如果不是,在不使用户语法过于复杂的情况下解决此问题的最佳方法是什么?
编辑: 将成员函数指针作为模板参数传递也是可以接受的,也许通过包装器。目标成员函数在编译时总是已知的。伪代码:
forwarder<WRAP<example::f0>>(10, 'a');
// Where WRAP can be a macro or a type alias.
我通过向成员函数指针提供模板参数在 gcc 4.9 中编译了您的代码; 像这样
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)
}
我相信您需要实例化模板成员函数。 这会改变你的界面吗? 我认为任何答案都将围绕以某种方式实例化该成员模板为中心。