Скрытие имени параметра шаблона
Меня недавно укусила (упрощенно)
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 решила не рассматривать изменение существующих правил в настоящее время без более детального изучения вопроса.
К сожалению, такая статья еще не была написана, и поэтому правило сохраняется до сегодняшнего дня.