Скрытие имени параметра шаблона
Недавно я был укушен (упрощен)
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
};
Какое обоснование (если таковое имеется) за этим, по-видимому, абсурдным правилом?
Единственный выход, о котором я могу думать, - дать уродливые имена параметров шаблона, а также означает, что невозможно безопасно написать шаблон без использования зарезервированных имен (поскольку класс, используемый в шаблоне, может столкнуться с именами параметров... обратите внимание, что много кода С++ использует uglfied names для частных членов).
PS: Я не копался в стандарте об этой проблеме, но как g++, так и clang++ согласны с этим поведением, поэтому я не думаю, что это ошибка.
PPS: в реальном коде скрытый параметр шаблона был назван tid
и был целым числом, а не типом. -Wall
было недостаточно для уведомления о скрытии, и я обнаружил его через пару часов отладки с valgrind.
Ответы
Ответ 1
Это правило (указанное в [temp.local]/9) является предметом проблемы открытого ядра, созданной более 11 лет назад - основная проблема # 459. КСР обсудила это полностью. О намерении, Майк Миллер упоминает, что
Обоснование текущей спецификации действительно очень просто:
-
"Если не указано в производном классе, члены базового класса также считаются членами производного класса". (10 [class.derived], пункт 2)
-
В области класса члены скрывают не-членов.
Что это. Поскольку параметры шаблона не являются членами, они скрытые именами пользователей (унаследованные или нет). Я не считаю, что "странно" или даже особенно удивительно.
Обоснование:
У нас есть некоторое сочувствие к изменению, но текущие правила прямо выходят из правил поиска, поэтому они не являются "неправильными". Частные члены, невидимые, также решают эту проблему. Мы хотели бы взглянуть на документ, предлагающий это. [..]
КХГ решила не рассматривать изменение существующих правил в настоящее время без более подробного изучения проблемы.
К сожалению, такая бумага еще не написана, и поэтому правило сохраняется до сегодняшнего дня.