class std::result_of 中没有名为 'type' 的类型
no type named 'type' in class std::result_of
以下代码无法编译:
template< typename Fn >
bool templateFunctionOne( Fn&& fn )
{
int v = 5;
return fn( v );
}
template < typename Fn >
bool templateFunctionTwo( Fn&& fn )
{
std::future< bool > tk( std::async( std::launch::async,
&templateFunctionOne< Fn >,
std::forward<Fn>(fn ) ) );
return tk.get();
}
bool printThis( int value )
{
cout << value << endl;
return true;
}
int main()
{
auto func = std::bind( &printThis, std::placeholders::_1 );
return templateFunctionTwo( func );
}
编译时出现以下错误:
functional::1665:61: error: no type named 'type' in 'class
std::result_of< bool ((std::_Bind(std::_Placeholder<1>))(int)>))(std::_Bind))(int)>&)>'
我简化了上面的内容,仍然不会编译并出现相同的错误消息:
template< typename Fn >
bool templateFunctionOne( Fn&& fn )
{
return fn();
}
template < typename Fn >
bool templateFunctionTwo( Fn&& fn )
{
std::future< bool > tk( std::async( std::launch::async,
&templateFunctionOne< Fn >,
std::forward<Fn>(fn ) ) );
return tk.get();
}
bool printThis()
{
return true;
}
int main()
{
auto func = std::bind( &printThis );
return templateFunctionTwo( func );
}
因为现在函数printThis
不需要传入任何参数,所以绑定调用是不必要的。当按如下方式更改 main 中的调用时,它编译得很好:
int main()
{
return templateFunctionTwo( &printThis );
}
谁能帮忙解释一下?在传递函数指针而不使用 std::ref
来包装需要引用的参数时,我看到了同样的错误,但这似乎是别的(或不是),我在这里错过了什么?
不需要绑定任何东西。
#include<thread>
#include<functional>
#include<utility>
#include<future>
#include<memory>
#include<iostream>
template< typename Fn >
bool templateFunctionOne( Fn&& fn )
{
int v = 5;
return fn( v );
}
template < typename Fn >
bool templateFunctionTwo( Fn&& fn )
{
std::future< bool > tk( std::async( std::launch::async,
&templateFunctionOne< Fn >,
std::forward<Fn>(fn ) ));
return tk.get();
}
bool printThis( int value )
{
std::cout << value << std::endl;
return true;
}
int main()
{
//auto func = std::bind( &printThis, std::placeholders::_1 );
return templateFunctionTwo( &printThis );
}
编译,执行时returns期望值5。
auto func = std::bind( &printThis );
return templateFunctionTwo( func );
func
是左值,所以当左值传入 templateFunctionTwo
时, Fn
被推断为 Fn&
(由于转发引用)。
下一行
&templateFunctionOne< Fn >,
表示
&templateFunctionOne< Fn& >,
这意味着 templateFunctionOne
通过引用获取其参数,
如果你想在调用 async
时通过引用传递参数
您需要使用包装器 std::ref
或 std::cref
:
std::future< bool > tk = std::async(
templateFunctionOne< Fn >,
std::ref( std::forward<Fn>(fn) ) ); // <--- ref added
现在您的代码可以编译了。
另一种方法是使用 remove_reference_t<Fn>
或
typename std::remove_reference<Fn>::type
从 Fn
:
中删除左值引用
std::future< bool > tk = std::async(
templateFunctionOne< std::remove_reference_t<Fn> >, // <--- remove_reference_t added
std::forward<Fn>(fn) );
return tk.get();
然后fn
对象按值传递。这个版本比第一个好,因为调用
templateFunctionTwo( std::bind( &printThis, std::placeholders::_1 ) )
在使用ref
时失败,因为ref
只需要取左值。
以下代码无法编译:
template< typename Fn >
bool templateFunctionOne( Fn&& fn )
{
int v = 5;
return fn( v );
}
template < typename Fn >
bool templateFunctionTwo( Fn&& fn )
{
std::future< bool > tk( std::async( std::launch::async,
&templateFunctionOne< Fn >,
std::forward<Fn>(fn ) ) );
return tk.get();
}
bool printThis( int value )
{
cout << value << endl;
return true;
}
int main()
{
auto func = std::bind( &printThis, std::placeholders::_1 );
return templateFunctionTwo( func );
}
编译时出现以下错误:
functional::1665:61: error: no type named 'type' in 'class std::result_of< bool ((std::_Bind(std::_Placeholder<1>))(int)>))(std::_Bind))(int)>&)>'
我简化了上面的内容,仍然不会编译并出现相同的错误消息:
template< typename Fn >
bool templateFunctionOne( Fn&& fn )
{
return fn();
}
template < typename Fn >
bool templateFunctionTwo( Fn&& fn )
{
std::future< bool > tk( std::async( std::launch::async,
&templateFunctionOne< Fn >,
std::forward<Fn>(fn ) ) );
return tk.get();
}
bool printThis()
{
return true;
}
int main()
{
auto func = std::bind( &printThis );
return templateFunctionTwo( func );
}
因为现在函数printThis
不需要传入任何参数,所以绑定调用是不必要的。当按如下方式更改 main 中的调用时,它编译得很好:
int main()
{
return templateFunctionTwo( &printThis );
}
谁能帮忙解释一下?在传递函数指针而不使用 std::ref
来包装需要引用的参数时,我看到了同样的错误,但这似乎是别的(或不是),我在这里错过了什么?
不需要绑定任何东西。
#include<thread>
#include<functional>
#include<utility>
#include<future>
#include<memory>
#include<iostream>
template< typename Fn >
bool templateFunctionOne( Fn&& fn )
{
int v = 5;
return fn( v );
}
template < typename Fn >
bool templateFunctionTwo( Fn&& fn )
{
std::future< bool > tk( std::async( std::launch::async,
&templateFunctionOne< Fn >,
std::forward<Fn>(fn ) ));
return tk.get();
}
bool printThis( int value )
{
std::cout << value << std::endl;
return true;
}
int main()
{
//auto func = std::bind( &printThis, std::placeholders::_1 );
return templateFunctionTwo( &printThis );
}
编译,执行时returns期望值5。
auto func = std::bind( &printThis );
return templateFunctionTwo( func );
func
是左值,所以当左值传入 templateFunctionTwo
时, Fn
被推断为 Fn&
(由于转发引用)。
下一行
&templateFunctionOne< Fn >,
表示
&templateFunctionOne< Fn& >,
这意味着 templateFunctionOne
通过引用获取其参数,
如果你想在调用 async
时通过引用传递参数
您需要使用包装器 std::ref
或 std::cref
:
std::future< bool > tk = std::async(
templateFunctionOne< Fn >,
std::ref( std::forward<Fn>(fn) ) ); // <--- ref added
现在您的代码可以编译了。
另一种方法是使用 remove_reference_t<Fn>
或
typename std::remove_reference<Fn>::type
从 Fn
:
std::future< bool > tk = std::async(
templateFunctionOne< std::remove_reference_t<Fn> >, // <--- remove_reference_t added
std::forward<Fn>(fn) );
return tk.get();
然后fn
对象按值传递。这个版本比第一个好,因为调用
templateFunctionTwo( std::bind( &printThis, std::placeholders::_1 ) )
在使用ref
时失败,因为ref
只需要取左值。