是否可以在自由函数可以使用 std::function 的任何地方使用成员函数?
Can a member function be used anywhere a free function can using std::function?
我有一些代码(由 GitHub 上的 progschj 提供),我已对其进行改编以举例说明我的问题。 MakeTask 将任何函数及其参数移动到 MakeTask 中,从而生成 packaged_task。创建的任务被执行,然后将其未来返回给调用者。这非常巧妙,但我也希望能够使用成员函数来做到这一点。但是,如果我将 Func 放入结构中,MakeTask 中的 F&& 将失败,并出现代码中指出的错误。
#include <future>
#include <memory>
#include <string>
#include <functional>
template<class F, class... Args>
auto MakeTask( F&& f, Args&&... args )-> std::future< typename std::result_of< F( Args... ) >::type >
{
typedef typename std::result_of< F( Args... ) >::type return_type;
auto task = std::make_shared< std::packaged_task< return_type() > >(
std::bind( std::forward< F >( f ), std::forward< Args >( args )... )
);
std::future< return_type > resultFuture = task->get_future();
( *task )( );
return resultFuture;
}
struct A
{
int Func( int nn, std::string str )
{
return str.length();
}
};
int main()
{
// error C2893: Failed to specialize function template 'std::future<std::result_of<_Fty(_Args...)>::type> MakeTask(F &&,Args &&...)'
// note: 'F=int (__thiscall A::* )(int,std::string)'
// note: 'Args={int, const char (&)[4]}'
auto resultFuture = MakeTask( &A::Func, 33, "bbb" ); // does not compile
int nn = resultFuture.get();
return 0;
}
如果我将 Func 变成静态的,我可以让它工作,但这会破坏我的应用程序代码的其他部分。
Edit1:我弄清楚了 std::function 的语法并使用新的错误消息修改了示例。 MakeTask 的 F&& 移动参数不接受我的 aFunc 作为可调用对象。
Edit2:由于 Barry 的回答,我将示例代码改回原始帖子,以便他的回答对未来的观众有意义。
&A::Func
是一个非静态成员函数,这意味着它需要一个 A
的实例来运行。所有函数 objects/adapters 使用的约定是提供的第一个参数将是那个实例。
MakeTask()
要求第一个参数 (F
) 可以与所有其他参数 (Args...
) 一起调用。 &A::Func
需要 三个 个参数:一个 A
类型的对象(或指向 A
或 reference_wrapper<A>
的指针),一个 int
,以及 string
。你只是错过了第一个:
auto resultFuture = MakeTask( &A::Func, A{}, 33, "bbb" );
^^^^^
我有一些代码(由 GitHub 上的 progschj 提供),我已对其进行改编以举例说明我的问题。 MakeTask 将任何函数及其参数移动到 MakeTask 中,从而生成 packaged_task。创建的任务被执行,然后将其未来返回给调用者。这非常巧妙,但我也希望能够使用成员函数来做到这一点。但是,如果我将 Func 放入结构中,MakeTask 中的 F&& 将失败,并出现代码中指出的错误。
#include <future>
#include <memory>
#include <string>
#include <functional>
template<class F, class... Args>
auto MakeTask( F&& f, Args&&... args )-> std::future< typename std::result_of< F( Args... ) >::type >
{
typedef typename std::result_of< F( Args... ) >::type return_type;
auto task = std::make_shared< std::packaged_task< return_type() > >(
std::bind( std::forward< F >( f ), std::forward< Args >( args )... )
);
std::future< return_type > resultFuture = task->get_future();
( *task )( );
return resultFuture;
}
struct A
{
int Func( int nn, std::string str )
{
return str.length();
}
};
int main()
{
// error C2893: Failed to specialize function template 'std::future<std::result_of<_Fty(_Args...)>::type> MakeTask(F &&,Args &&...)'
// note: 'F=int (__thiscall A::* )(int,std::string)'
// note: 'Args={int, const char (&)[4]}'
auto resultFuture = MakeTask( &A::Func, 33, "bbb" ); // does not compile
int nn = resultFuture.get();
return 0;
}
如果我将 Func 变成静态的,我可以让它工作,但这会破坏我的应用程序代码的其他部分。
Edit1:我弄清楚了 std::function 的语法并使用新的错误消息修改了示例。 MakeTask 的 F&& 移动参数不接受我的 aFunc 作为可调用对象。
Edit2:由于 Barry 的回答,我将示例代码改回原始帖子,以便他的回答对未来的观众有意义。
&A::Func
是一个非静态成员函数,这意味着它需要一个 A
的实例来运行。所有函数 objects/adapters 使用的约定是提供的第一个参数将是那个实例。
MakeTask()
要求第一个参数 (F
) 可以与所有其他参数 (Args...
) 一起调用。 &A::Func
需要 三个 个参数:一个 A
类型的对象(或指向 A
或 reference_wrapper<A>
的指针),一个 int
,以及 string
。你只是错过了第一个:
auto resultFuture = MakeTask( &A::Func, A{}, 33, "bbb" );
^^^^^