4
從this question開始的延續。我試圖綁定一個給定的函數,該函數返回一些其他的東西,而不是void,以便稍後可以簡單地調用f()。但是,以下代碼無法在GCC 4.4上編譯。它在VS 2010上編譯,但由此產生的程序崩潰。從模板內綁定模板功能
template<typename RetType>
void _hideRet(std::function<RetType()> func, RetType * ret)
{
*ret = func();
}
template<typename FuncType, typename RetType, typename ParamType>
std::function<void()> registerFunc(FuncType func, RetType * ret, ParamType param)
{
auto f = std::bind(func, std::forward<ParamType>(param));
return std::bind(_hideRet<RetType>, f, ret);
}
int myFunction(std::string text)
{
std::cout << text << std::endl;
return 42;
}
int main()
{
int ret = 0;
auto f = registerFunc(myFunction, &ret, "text");
f();
std::cout << ret << std::endl;
return 0;
}
GCC產生這種瘋狂的消息:
In file included from /usr/include/c++/4.4/functional:70,
from func.cpp:4:
/usr/include/c++/4.4/tr1_impl/functional: In member function ‘typename std::result_of<_Functor(typename std::result_of<std::_Mu<_Bound_args, std::is_bind_expression::value, (std::is_placeholder::value > 0)>(_Bound_args, std::tuple<_UElements ...>)>::type ...)>::type std::_Bind<_Functor(_Bound_args ...)>::__call(const std::tuple<_UElements ...>&, std::_Index_tuple<_Indexes ...>) [with _Args = , int ..._Indexes = 0, 1, _Functor = void (*)(std::function<int()>, int*), _Bound_args = std::_Bind<int (*(const char*))(std::string)>, int*]’:
/usr/include/c++/4.4/tr1_impl/functional:1191: instantiated from ‘typename std::result_of<_Functor(typename std::result_of<std::_Mu<_Bound_args, std::is_bind_expression::value, (std::is_placeholder::value > 0)>(_Bound_args, std::tuple<_UElements ...>)>::type ...)>::type std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args& ...) [with _Args = , _Functor = void (*)(std::function<int()>, int*), _Bound_args = std::_Bind<int (*(const char*))(std::string)>, int*]’
/usr/include/c++/4.4/tr1_impl/functional:1668: instantiated from ‘static void std::_Function_handler<void(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Functor = std::_Bind<void (*(std::_Bind<int (*(const char*))(std::string)>, int*))(std::function<int()>, int*)>, _ArgTypes = ]’
/usr/include/c++/4.4/tr1_impl/functional:2005: instantiated from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor, typename __gnu_cxx::__enable_if<(! std::is_integral::value), std::function<_Res(_ArgTypes ...)>::_Useless>::__type) [with _Functor = std::_Bind<void (*(std::_Bind<int (*(const char*))(std::string)>, int*))(std::function<int()>, int*)>, _Res = void, _ArgTypes = ]’
func.cpp:16: instantiated from ‘std::function<void()> registerFunc(FuncType, RetType*, ParamType) [with FuncType = int (*)(std::string), RetType = int, ParamType = const char*]’
func.cpp:28: instantiated from here
/usr/include/c++/4.4/tr1_impl/functional:1137: error: invalid conversion from ‘int’ to ‘std::_M_clear_type*’
/usr/include/c++/4.4/tr1_impl/functional:1137: error: initializing argument 1 of ‘std::function<_Res(_ArgTypes ...)>::function(std::_M_clear_type*) [with _Res = int, _ArgTypes = ]’
我沒有內部STL運作的足夠的知識來做出什麼出格的那個。
但同時實驗,我發現,如果我從registerFunc模板中刪除第二std::bind
調用是這樣的:
template<typename FuncType, typename RetType, typename ParamType>
std::function<RetType()> registerFunc(FuncType func, RetType *, ParamType param)
{
return std::bind(func, std::forward<ParamType>(param));
}
// in main
auto tmp = registerFunc(myFunction, &ret, "text");
auto f = std::bind(_hideRet<int>, tmp, &ret);
f();
的代碼工作無論是在VS和海灣合作委員會的預期。所以我的結論是,問題是在模板函數中調用std::bind(_hideRet<RetType>, ...)
。問題是爲什麼這是一個問題?更重要的是如何解決這個問題?
謝謝,我可以證實這個解決方法也滿足GCC。 – Fiktik 2010-12-19 18:42:07
@Fiktik:我希望我明白爲什麼:)你的原始代碼應該從我的角度來看 – icecrime 2010-12-19 18:47:35
ParamType可能是錯誤的,並且實例化爲const char *,而正確的ParamType是'std :: string'。 – smerlin 2010-12-19 21:40:38