gpt4 book ai didi

c++ - 如何在推导上下文中将 std::bind(或 lambda)转换为 std::function?

转载 作者:搜寻专家 更新时间:2023-10-31 02:13:25 26 4
gpt4 key购买 nike

我正在尝试将指向成员函数的指针(使用 std::bind 或 lambda)转换为 std::function。我的尝试(根据 this answer on SO 的回答)看起来像这样:

#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

最佳答案

很难从 lambda 或 std::bind 返回类型中推断出参数,因此您可能希望延迟 toFunction 中的绑定(bind),例如与:

template<typename C, typename Ret, typename... Args, typename... BArgs>
auto toFunction(Ret (C::*f)(Args...), BArgs&&... bargs) {
return std::function<Ret(Args...)>(std::bind(f, std::forward<BArgs>(bargs)...));
}

这样,您可以使用以下方法检索 std::function:

auto f = toFunction(&MyStruct::f, &m, std::placeholders::_1);
f(2);

关于c++ - 如何在推导上下文中将 std::bind(或 lambda)转换为 std::function?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41466082/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com