std :: forward для пересылки функции

У меня есть следующий код, который просто не компилируется, особенно после его пересылки через 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 функция просто не может быть вызвана? В базовом классе, прямо перед вызовом testAtNextLevel, если выполняются некоторые условия, мы можем просто вызвать переданную функцию, но не после того, как она будет перенаправлена ​​в другую шаблонную функцию?

0

Решение

Со всеми этими шаблонами и auto декларации, становится легко потерять отслеживание того, с каким типом данных вы имеете дело. Давайте начнем с нижней части вашего кода:

auto myFunc = std::bind( &TestChild::thisTestOk, this );

Что такое myFunc? В то время как тип возврата std::bind официально не указано, указано его использование (см., например, cppreference.com). Вызов этого возвращаемого значения как функции эквивалентен вызову thisTestOk() с его единственным аргументом, связанным с this,

То есть скрытый указатель наTestChild аргумент (присутствует во всех TestChildнестатические функции-члены) был заменен this, который имеет эффект преобразования функции-члена в функцию, не являющуюся членом. Теперь давайте посмотрим, как вы вызываете эту функцию, не являющуюся членом оболочки.

В test()эта обертка вызывается через return fn(), Он вызывается как функция и работает как задумано.

В testAtNextLevel()эта обертка вызывается через this->*fn(), Эта обертка нечлен Функция вызывается как указатель на функцию-член, что является ошибкой. Чтобы он работал синтаксически, вызов должен быть просто fn()как это было в test(), Если вы действительно хотите переопределить связанный объект и использовать this как скрытый аргумент fn()вам нужно передать что-то другое в качестве аргумента testAtNextLevel(), вероятно, указатель на член (и это должен быть указатель наTestParentчлен, а не указатель наTestChild-Член).

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]