Недавно я был укушен (упрощен)
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.