Скрытие имени параметра шаблона

Меня недавно укусила (упрощенно)

struct Base {
    typedef char T;
};

template<typename T>
struct Foo : Base {
    T x[50];  // This is Base::T, not the template parameter
};

Другими словами, имя члена класса скрывает параметр шаблона (даже если он исходит из базового класса, поэтому не является полностью очевидным в локальном контексте).

Проведя некоторый эксперимент, я обнаружил, что:

struct Base {
    typedef char T;
};

template<typename T, typename B>
struct Foo : B {
    T x[50];  // This T is the template parameter,
              // even passing Base as B
};

Каково обоснование (если таковое имеется) за этим явно абсурдным правилом?

Единственный выход, о котором я могу подумать, это дать некрасивые имена параметров шаблона, а также означает, что невозможно безопасно написать шаблон без использования зарезервированных имен (поскольку класс, используемый в шаблоне, может конфликтовать с именами параметров... обратите внимание, что много C++ код использует неприглядные имена для частных пользователей).

PS: я не копался в стандарте по этому вопросу, но и g++, и clang++ согласны с таким поведением, поэтому я не думаю, что это ошибка.

PPS: в реальном коде скрытый параметр шаблона был назван tidи был целым числом, а не типом. -Wall не было достаточно, чтобы уведомить о сокрытии, и я обнаружил это после пары часов отладки с помощью valgrind.

1 ответ

Решение

Это правило (указанное в [temp.local] / 9) является предметом проблемы с открытым основным языком, созданной более 11 лет назад - основной проблемой # 459. CWG тщательно это обсудила. О намерении Майк Миллер упоминает, что

Обоснование текущей спецификации действительно очень просто:

  • "Если не объявлено повторно в производном классе, члены базового класса также считаются членами производного класса". (10 [class.derived] параграф 2)

  • В рамках класса члены скрывают не членов.

Вот и все. Поскольку параметры шаблона не являются членами, они скрыты по именам элементов (наследуемых или нет). Я не нахожу это "странным" или даже особенно удивительным.

Обоснование:

У нас есть некоторое сочувствие к изменению, но текущие правила прямо не соответствуют правилам поиска, поэтому они не являются "неправильными". Создание частных невидимых пользователей также решило бы эту проблему. Мы были бы готовы взглянуть на статью, предлагающую это.[..]
CWG решила не рассматривать изменение существующих правил в настоящее время без более детального изучения вопроса.

К сожалению, такая статья еще не была написана, и поэтому правило сохраняется до сегодняшнего дня.

Другие вопросы по тегам