Я сталкивался со следующей ситуацией в одном из моих проектов, где базовый класс имеет шаблон функции, который скрыт не шаблонной функцией в шаблоне производного класса. Далее по иерархии классов функция без шаблонов явно переносит функцию в область действия с помощью директивы using.
Вот упрощенный пример кода:
class Base
{
public:
template<typename T> const T& get() const;
};
template<typename T> class Derived : public Base
{
private:
using Base::get;
public:
const T& get() const;
};
template<typename T> class MoreDerived : public Derived<T>
{
public:
using Derived<T>::get; // <-- this causes the problem
const T& call_get() {
return get();
}
};
template class MoreDerived<int>;
Годболт: https://godbolt.org/z/5MQ0VL
Приведенный выше код не работает в GCC и Clang с такими ошибками:
<source>:15:28: error: 'template<class T> const T& Base::get() const' is inaccessible within this context
15 | template<typename T> class MoreDerived : public Derived<T>
MSVC и ICC принимают этот код без жалоб.
Мне интересно, почему компиляторы жалуются на Base::get<T>
в то время как там есть публичная перегрузка Derived<T>::get
доступна?
Удаление частного using Base::get
из Derived<T>
приводит к предупреждению о сокрытии функций от базового класса. Так что, к сожалению, это тоже не идеальный вариант.
Без using Derived<T>::get
вызовы get
должны быть квалифицированы в пределах MoreDerived
, так как в противном случае это не было бы зависимое имя.
Есть идеи, что я тут не так делаю?