This question is a follow up of
Moving a member function from base class to derived class breaks the program for no obvious reason (this is a prime example of why one shouldn't use
using namespace std;
using namespace std;
struct D : B<T>
return this->bitset < 32;
In member function 'bool D<T>::foo(T, std::__cxx11::string)': cpp/scratch/minimal.cpp:24:22: error: invalid use of 'class std::bitset<1ul>'
return this->bitset == 32;
this->bitset < 32
tl;dr it looks like this is a deliberate decision, specifically to support the alternate syntax you already used.
An approximate walkthrough of the standardese below:
this-> B < ^
this->Bdoes name something, but it's a template
B<T>, so keep going
Bon it's own also names something, a class template
this->B<T>as a qualifier, and it isn't a less-than after all
In the other case,
proceeds identically until the third step, when it realises there are two different things called
bitset (a template class member and a class template), and just gives up.
This is from a working draft I have lying around, so not necessarily the most recent, but:
3.4.5 Class member access [basic.lookup.classref ]
1In a class member access expression (5.2.5), if the . or -> token is immediately followed by an identifier followed by a <, the identifier must be looked up to determine whether the < is the beginning of a template argument list (14.2) or a less-than operator. The identifier is first looked up in the class of the object expression. If the identifier is not found, it is then looked up in the context of the entire postfix-expression and shall name a class template. If the lookup in the class of the object expression finds a template, the name is also looked up in the context of the entire postfix-expression and
- if the name is not found, the name found in the class of the object expression is used, otherwise
- if the name is found in the context of the entire postfix-expression and does not name a class template, the name found in the class of the object expression is used, otherwise
- if the name found is a class template, it shall refer to the same entity as the one found in the class of the object expression, otherwise the program is ill-formed.
So, in any expression like
this->id < ..., it has to handle cases where
id<... is the start of a template identifier (like
It still checks the object first, but if
this->id finds a template, further steps apply. And in your case,
this->bitset is presumably considered a template as it still depends on
T, so it finds the conflicting
std::bitset and fails at the third bullet above.