std::bind
またはlambdaを使用して、メンバー関数へのポインタをstd::function
に変換しようとしています。 (this answer on SOからの回答後)私の試みはそうのようになります。どのようにstd :: bind(またはlambda)を推定コンテキストでstd :: functionに変換するのですか?
#include <functional>
template<typename T>
struct AsFunction :
AsFunction<decltype(&T::operator())>
{};
template<class ReturnType, class... Args>
struct AsFunction<ReturnType(Args...)> {
using type = std::function<ReturnType(Args...)>;
};
template<class ReturnType, class... Args>
struct AsFunction<ReturnType(*)(Args...)> {
using type = std::function<ReturnType(Args...)>;
};
template<class Class, class ReturnType, class... Args>
struct AsFunction<ReturnType(Class::*)(Args...) const> {
using type = std::function<ReturnType(Args...)>;
};
template<class F>
auto toFunction(F f) -> typename AsFunction<F>::type {
return {f};
}
struct MyStruct {
int x,y;
void f(int){};
};
int main(){
MyStruct m;
{
// this works
auto f = std::bind(&MyStruct::f, &m, std::placeholders::_1);
f(2);
}
{
// this doesn't
auto f = toFunction(std::bind(&MyStruct::f, &m, std::placeholders::_1));
f(2);
}
{
// .. neither does this
auto f = toFunction([m](int x) mutable { m.f(x); });
f(2);
}
}
が、私は、コンパイラから次のエラーメッセージが出ます:
// first not working
main.cpp:24:6: note: substitution of deduced template arguments resulted in errors seen above
main.cpp: In instantiation of ‘struct AsFunction<std::_Bind<std::_Mem_fn<void (MyStruct::*)(int)>(MyStruct*, std::_Placeholder<1>)> >’:
main.cpp:24:6: required by substitution of ‘template<class F> typename AsFunction<F>::type toFunction(F) [with F = std::_Bind<std::_Mem_fn<void (MyStruct::*)(int)>(MyStruct*, std::_Placeholder<1>)>]’
main.cpp:44:75: required from here
main.cpp:4:8: error: decltype cannot resolve address of overloaded function
struct AsFunction :
^~~~~~~~~~
main.cpp: In function ‘int main()’:
main.cpp:44:75: error: no matching function for call to ‘toFunction(std::_Bind_helper<false, void (MyStruct::*)(int), MyStruct*, const std::_Placeholder<1>&>::type)’
auto f = toFunction(std::bind(&MyStruct::f, &m, std::placeholders::_1));
^
main.cpp:24:6: note: candidate: template<class F> typename AsFunction<F>::type toFunction(F)
auto toFunction(F f) -> typename AsFunction<F>::type {
^~~~~~~~~~
main.cpp:24:6: note: substitution of deduced template arguments resulted in errors seen above
// second non working braces with lambda
main.cpp: In instantiation of ‘struct AsFunction<void (main()::<lambda(int)>::*)(int)>’:
main.cpp:4:8: required from ‘struct AsFunction<main()::<lambda(int)> >’
main.cpp:24:6: required by substitution of ‘template<class F> typename AsFunction<F>::type toFunction(F) [with F = main()::<lambda(int)>]’
main.cpp:50:55: required from here
main.cpp:5:23: error: ‘operator()’ is not a member of ‘void (main()::<lambda(int)>::*)(int)’
AsFunction<decltype(&T::operator())>
^~
main.cpp:50:55: error: no matching function for call to ‘toFunction(main()::<lambda(int)>)’
auto f = toFunction([m](int x) mutable { m.f(x); });
^
main.cpp:24:6: note: candidate: template<class F> typename AsFunction<F>::type toFunction(F)
auto toFunction(F f) -> typename AsFunction<F>::type {
^~~~~~~~~~
main.cpp:24:6: note: substitution of deduced template arguments resulted in errors seen above
@Holt私はOPは、結果の型と引数の型を推論したいと思います。私は正しい? –
@ W.F。正確に(後でそれらを操作したい) – Patryk
さて、* lambda *または 'std :: bind'を本当に使用する必要がありますか? 'toFunction(&MyStruct :: f、&m)'は大丈夫でしょうか? "lambda type"と 'std :: bind'の戻り値はインプリメンテーション定義であるため、テンプレート引数を推測するのに常に使用するのは難しいです... – Holt