The other day, I discovered that this was possible:
template <class T> struct base {};
struct derived: base<int> {};
int main()
{
// The base class template is accessible here
typename derived::base<double> x;
// from the comments, even this works
typename derived::derived::base<double>::base<int>::base<void> y;
}
I have no recollection of ever reading this on cppreference or in C++ tutorials, or this being exploited in clever template metaprogramming tricks (because I'm sure it can be). I have several questions:
- Does this thing have a specific name?
- Where is it documented in the C++ standard and on cppreference?
- Is there any template metaprogramming trick exploiting this?
base<double>
isn't a base class ofderived<int>
. – Panopticbase
and template type onderived
. – Cribworkbase<double>
with the namespacespace
, in this example usingderived<int>
seems to accomplish the same thing. – Panopticstd::enable_if<>::type
. Same thing. Upd: not only base, but self class is also accessible: so you can write liketypename derived::derived::derived::derived::base<double>::base<double>::base<double>::base<double> x;
– Zoolatryderived
can be repeated has been discussed multiple times on SO. – Erasmoerasmus<source>:7:57: warning: ISO C++ specifies that qualified reference to 'base' is a constructor name rather than a template name in this context, despite preceding 'typename' keyword [-Winjected-class-name] typename derived::derived::base<double>::base<int>::base<void> x;
with an arrow pointing at the start of the lastbase
. – Erasmoerasmusbase
is no longer in a remote namespace. – Destabase
is defined in the context ofderived
? I never thought about it but it makes sense that it would be. What really surprises me is @NirFriedman's note that it names a constructor function and not a type; normally constructors can't be called by name. – Cribworktypename
specifier, functions are ignored (IIRC). – Fungiform