在試圖實現一個委託 -class使用可變參數模板我遇到了一個問題,我無法來解決:C++ 11 - 使用decltype函數指針有什麼問題?
/// --------------------------------------
/// @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編譯器來編譯在Ideone( GCC 4.7.2),但似乎失敗:
prog.cpp: In instantiation of ‘Delegate& Delegate::bind(Return (*)(Param, ParamsOther ...)) [with Return = int; Param = int; ParamsOther = {}]’: prog.cpp:79:23: required from here prog.cpp:45:5: error: no matches converting function ‘_wrap_function_static’ to type ‘int (*)(int)’ prog.cpp:39:26: error: candidate is: template static Return Delegate::_wrap_function_static(void*, Param, ParamsOther ...) [with Return (* Function)(Param, ParamsOther ...) = Function; Return = int; Param = int; ParamsOther = {}] prog.cpp: In instantiation of ‘Return Delegate::operator()(Param, ParamsOther ...) const [with Return = int; Param = int; ParamsOther = {}]’: prog.cpp:80:40: required from here prog.cpp:59:65: error: invalid conversion from ‘void*’ to ‘int’ [-fpermissive] prog.cpp:59:65: error: too many arguments to function
從我可以理解,decltype和樂趣ction指針這裏
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和函數指針場景有什麼問題?
這是完全不清楚你正在嘗試做什麼。您將函數指針傳遞給'bind',但'bind'從不使用其參數的值。你是否計劃稍後能夠調用傳遞的函數? – 2013-05-07 20:23:36
'template static inline返回_wrap_function_static /*...*/'期待函數指針作爲非類型模板參數。 '&_wrap_function_static '提供了一個函數指針類型作爲模板參數。 –
dyp
2013-05-07 20:46:03
哦,順便說一句。爲什麼不使用'std :: bind'和'std :: function'? – dyp 2013-05-07 20:47:20