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

Недавно я был укушен (упрощен)

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)

  • В области класса члены скрывают не-членов.

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

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

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

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