Проблема, с которой вы сталкиваетесь, называется сокрытием.В основном правила поиска в языке будут начинаться с самого производного типа и работать обратно до тех пор, пока не найдет соответствующий символ.В вашем случае он остановится, глядя на класс B
, который находит void B::foo(const std::string& name)
.На этом уровне единственная потенциальная перегрузка, которую он будет учитывать, это та, которую он видит.
Чтобы избежать сокрытия, вы можете перенести все другие перегрузки, которые вы можете добавить декларацией using
:
struct B : A{
using A::foo;
void foo( const std::string & name );
};
Разница в том, что поиск будет работать по иерархии до тех пор, пока не найдет первую перегрузку, которая снова находится на уровне B
, но из-за директивы using
он также будет учитывать любую перегрузку, доступную в A
.
В качестве альтернативы, вы можете оставить символ скрытым и принудительно отправить диспетчер точному классу, квалифицируя вызов (обратите внимание, что это имеет побочный эффект отключения динамической диспетчеризации, что не является проблемой здесь, но может быть, еслиперегрузка для использования является виртуальной):
b->A::foo<X>();