在尝试使用可变参数模板实现Delegate类时,我遇到了一个我无法解决的问题:
/// --------------------------------------
/// @thanks God
/// Steve Reinalter
/// @author Henri Korpela aka Helixirr
/// --------------------------------------
#include <cstdio>
template<typename>
class Delegate;
template<typename Return, typename Param, typename... ParamsOther>
class Delegate<Return (Param, ParamsOther...)>{
public:
/// Constructors & destructors:
Delegate(void) = default;
Delegate(Delegate const& delegate_) = default;
Delegate(Delegate&& delegate_) = default;
/// Member functions:
Delegate& bind(Return (*function_)(Param, ParamsOther...));
template<class C>
Delegate& bind(C& c_, Return (C::*function_)(Param, ParamsOther...));
/// Member functions (overloaded operators, assignment):
Delegate& operator=(Delegate const& delegate_) = default;
Delegate& operator=(Delegate&& delegate_) = default;
/// Member functions (overloaded operators, function call):
inline Return operator()(Param param_, ParamsOther... params_other_) const;
private:
/// Member data:
Return (*_m_opFunction)(Param, ParamsOther...) = nullptr;
void* _m_opInstance = nullptr;
/// Static member functions:
template<class C, Return (C::*Function)(Param, ParamsOther...)>
static inline Return _wrap_function_member(void* instance_, Param param_, ParamsOther... params_other_);
template<Return (*Function)(Param, ParamsOther...)>
static inline Return _wrap_function_static(void*, Param param_, ParamsOther... params_other_);
};
/// Member functions:
template<typename Return, typename Param, typename... ParamsOther>
Delegate<Return (Param, ParamsOther...)>& Delegate<Return (Param, ParamsOther...)>::bind(Return (*function_)(Param, ParamsOther...)){
_m_opFunction = &_wrap_function_static<decltype(function_)>;
_m_opInstance = nullptr;
return *this;
}
template<typename Return, typename Param, typename... ParamsOther>
template<class C>
Delegate<Return (Param, ParamsOther...)>& Delegate<Return (Param, ParamsOther...)>::bind(C& c_, Return (C::*function_)(Param, ParamsOther...)){
_m_opFunction = &_wrap_function_member<C, decltype(function_)>;
_m_opInstance = &c_;
return *this;
}
/// Member functions (overloaded operators, function call):
template<typename Return, typename Param, typename... ParamsOther>
Return Delegate<Return (Param, ParamsOther...)>::operator()(Param param_, ParamsOther... params_other_) const{
return _m_opFunction(_m_opInstance, param_, params_other_...);
}
/// Static member functions:
template<typename Return, typename Param, typename... ParamsOther>
template<class C, Return (C::*Function)(Param, ParamsOther...)>
Return Delegate<Return (Param, ParamsOther...)>::_wrap_function_member(void* instance_, Param param_, ParamsOther... params_other_){
return (static_cast<C*>(instance_)->*Function)(param_, params_other_...);
}
template<typename Return, typename Param, typename... ParamsOther>
template<Return (*Function)(Param, ParamsOther...)>
Return Delegate<Return (Param, ParamsOther...)>::_wrap_function_static(void*, Param param_, ParamsOther... params_other_){
return (Function)(param_, params_other_...);
}
int f(int i_){
return i_ * 2;
}
int main(void){
Delegate<int (int)> delegate__;
delegate__.bind(&f);
printf("Result: %i\n", delegate__(8));
return 0;
}
我尝试使用 C++11 编译器(GCC 4.7.2 )在Ideone上编译它,但它似乎失败了:
prog.cpp: 在 'Delegate& Delegate::bind(Return (*)(Param, ParamsOther ...)) 的实例化中 [with Return = int; 参数 = 整数;ParamsOther = {}]': prog.cpp:79:23: 需要从这里 prog.cpp:45:5: 错误: 不匹配转换函数'_wrap_function_static' 到类型'int (*)(int)' prog.cpp: 39:26:错误:候选人是:模板静态返回委托::_wrap_function_static(void*, Param, ParamsOther ...) [with Return (* Function)(Param, ParamsOther ...) = Function; 返回 = 整数;参数 = 整数;ParamsOther = {}] prog.cpp:在 'Return Delegate::operator()(Param, ParamsOther ...) 的实例化中 const [with Return = int; 参数 = 整数;ParamsOther = {}]': prog.cpp:80:40: 需要从这里 prog.cpp:59:65: 错误: 从 'void*' 到 'int' 的无效转换 [-fpermissive] prog.cpp:59:65 : 错误: 函数参数太多
据我所知,decltype和函数指针here
template<typename Return, typename Param, typename... ParamsOther>
Delegate<Return (Param, ParamsOther...)>& Delegate<Return (Param, ParamsOther...)>::bind(Return (*function_)(Param, ParamsOther...)){
_m_opFunction = &_wrap_function_static<decltype(function_)>;
_m_opInstance = nullptr;
return *this;
}
似乎是造成问题的原因。当我尝试将成员函数绑定到委托时也会发生同样的情况。为什么会这样?我究竟做错了什么?对我来说,获取函数指针的类型并将该类型用作模板参数似乎很自然,但由于某种原因,它在这里不起作用。这个 decltype 和函数指针场景有什么问题?