I got recently bitten by (simplified)
struct Base {
typedef char T;
};
template<typename T>
struct Foo : Base {
T x[50]; // This is Base::T, not the template parameter
};
In other words a class member name hides a template parameter (even if coming from a base class, thus not being totally evident in the local context).
Making some experiment I found however that:
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
};
What is the rationale (if any) behind this apparently absurd rule?
The only way out I can think to is to give ugly template parameter names and also means that it's impossible to write safely a template without using reserved names (as class used in the template could clash parameter names... note that a lot of C++ code uses uglyfied names for private members).
PS: I didn't dig in the standard about the issue but both g++ and clang++ agree on this behavior so I don't think it's a bug.
PPS: In the real code the template parameter being hidden was named tid
, and was an integer and not a type. -Wall
was not enough to notifiy about the hiding and I discovered it after a couple of hours of debugging with valgrind.
tid
, and was an integer and not a type.-Wall
was not enough to notifiy about the hiding and I discoverd it after a couple of hours of debugging with valgrind. – CorkhillT
is already in scope; in the secondT
is unambiguously the template parameter, as there is no way of knowing beforehand that it might refer to a typeT
in the base class. – Approachable