Со всеми этими шаблонами и объявлениями 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
члена).