포인터를 std::bind
또는 lambdas를 사용하여 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 나는 영업 이익은 결과 유형과 인수의 유형을 추론하고자 생각합니다. 내가 맞습니까? –
@ W.F. 정확하게 (나중에 조작하고 싶다) – Patryk
좋아, * lambda * 또는'std :: bind'를 정말로 사용해야합니까? 'toFunction (& MyStruct :: f, & m)'괜찮습니까? "lambda type"과'std :: bind'의 리턴은 구현에 따라 정의되기 때문에 항상 템플릿 인자를 추론하는데 사용하기가 어렵습니다 ... – Holt