Почему я не могу вызвать шаблонный метод из экземпляра производного класса в C ++? - PullRequest
3 голосов
/ 17 мая 2011

Обратите внимание на следующие типы:

struct X
{
    static std::string fullyQualifiedName();
};


struct A
{
    template <class T> void foo()
    {
        return foo(T::fullyQualifiedName());
    }

protected:
    virtual void foo(const std::string& name) = 0;
};


struct B : public A
{
protected:
    void foo(const std::string& name);
};

У меня есть указатель на экземпляр B, я пытаюсь вызвать шаблонную версию foo, например, так:

b->foo< X >();

Компилятор жалуется: 'X': незаконное использование этого типа в качестве выражения.

С другой стороны, этот код в порядке:

A* a = b;
a->foo< X >();

Отсюда мой вопрос.

1 Ответ

9 голосов
/ 17 мая 2011

Проблема, с которой вы сталкиваетесь, называется сокрытием.В основном правила поиска в языке будут начинаться с самого производного типа и работать обратно до тех пор, пока не найдет соответствующий символ.В вашем случае он остановится, глядя на класс 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>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...