std::forward转发功能
std::forward to forward a funciton
我有以下代码无法编译,尤其是在通过 std::forward
转发之后
struct TestParent
{
template< typename Fn >
bool test( Fn&& fn )
{
//.. do something
//.. check some condition
bool someCondition = true;
if ( someCondition )
{
//this call works!
return fn();
}
return testAtNextLevel( std::forward< Fn >( fn ) );
}
template < typename Fn >
bool testAtNextLevel( Fn&& fn )
{
if ( (this->*fn() )
{
return true;
}
//... test some more
return true;
}
}
struct TestChild: public TestParent
{
bool thisTestOk();
bool testAll();
}
bool TestChild::thisTestOk()
{
return true;
}
bool testAll()
{
auto myFunc = std::bind( &TestChild::thisTestOk, this );
return test( myFunc );
}
编译时我收到了这个错误信息:
error: no match for 'operator->*' (operand types are 'TestParent*' and 'std::_Bind<std::_Mem_fn<bool (TestChild::*)()>(TestChild*)>')
if ( (this->*fn)() )
有人知道为什么在经历 std::forward 之后,函数就是无法调用吗?在基础 class,就在调用 'testAtNextLevel' 之前,如果满足某些条件,我们可以只调用传入的函数,而不是在它被转发到另一个模板函数之后?
使用所有这些模板和 auto
声明,很容易忘记您正在处理的数据类型。让我们从代码的底部开始:
auto myFunc = std::bind( &TestChild::thisTestOk, this );
什么是myFunc
?虽然 std::bind
的 return 类型未被正式指定,但它的用途是指定的(例如,参见 cppreference.com)。将此 returned 值作为函数调用等同于调用 thisTestOk()
并将其单独的参数绑定到 this
.
也就是说,指向 TestChild
参数的隐藏指针(存在于 TestChild
的所有非静态成员函数中)已被 this
取代,它具有将成员函数转换为非成员函数的效果。现在让我们看看如何调用这个包装器非成员函数。
在 test()
中,此包装器通过 return fn()
调用。它作为一个函数被调用,并按预期工作。
在 testAtNextLevel()
中,此包装器通过 this->*fn()
调用。此包装器 非成员 函数作为指向成员函数的指针被调用,这是一个错误。为了使其在句法上起作用,调用应该只是 fn()
,就像在 test()
中一样。如果你真的想覆盖绑定对象并使用 this
作为 fn()
的隐藏参数,你需要传递一些不同的东西作为 testAtNextLevel()
的参数,可能是指向成员的指针(而且它必须是指向 TestParent
成员的指针,而不是指向 TestChild
成员的指针)。
我有以下代码无法编译,尤其是在通过 std::forward
转发之后struct TestParent
{
template< typename Fn >
bool test( Fn&& fn )
{
//.. do something
//.. check some condition
bool someCondition = true;
if ( someCondition )
{
//this call works!
return fn();
}
return testAtNextLevel( std::forward< Fn >( fn ) );
}
template < typename Fn >
bool testAtNextLevel( Fn&& fn )
{
if ( (this->*fn() )
{
return true;
}
//... test some more
return true;
}
}
struct TestChild: public TestParent
{
bool thisTestOk();
bool testAll();
}
bool TestChild::thisTestOk()
{
return true;
}
bool testAll()
{
auto myFunc = std::bind( &TestChild::thisTestOk, this );
return test( myFunc );
}
编译时我收到了这个错误信息:
error: no match for 'operator->*' (operand types are 'TestParent*' and 'std::_Bind<std::_Mem_fn<bool (TestChild::*)()>(TestChild*)>')
if ( (this->*fn)() )
有人知道为什么在经历 std::forward 之后,函数就是无法调用吗?在基础 class,就在调用 'testAtNextLevel' 之前,如果满足某些条件,我们可以只调用传入的函数,而不是在它被转发到另一个模板函数之后?
使用所有这些模板和 auto
声明,很容易忘记您正在处理的数据类型。让我们从代码的底部开始:
auto myFunc = std::bind( &TestChild::thisTestOk, this );
什么是myFunc
?虽然 std::bind
的 return 类型未被正式指定,但它的用途是指定的(例如,参见 cppreference.com)。将此 returned 值作为函数调用等同于调用 thisTestOk()
并将其单独的参数绑定到 this
.
也就是说,指向 TestChild
参数的隐藏指针(存在于 TestChild
的所有非静态成员函数中)已被 this
取代,它具有将成员函数转换为非成员函数的效果。现在让我们看看如何调用这个包装器非成员函数。
在 test()
中,此包装器通过 return fn()
调用。它作为一个函数被调用,并按预期工作。
在 testAtNextLevel()
中,此包装器通过 this->*fn()
调用。此包装器 非成员 函数作为指向成员函数的指针被调用,这是一个错误。为了使其在句法上起作用,调用应该只是 fn()
,就像在 test()
中一样。如果你真的想覆盖绑定对象并使用 this
作为 fn()
的隐藏参数,你需要传递一些不同的东西作为 testAtNextLevel()
的参数,可能是指向成员的指针(而且它必须是指向 TestParent
成员的指针,而不是指向 TestChild
成员的指针)。