c++ - Template dependent base member is not resolved properly -
this question follow of moving member function base class derived class breaks program no obvious reason (this prime example of why 1 shouldn't use using namespace std;
)
where answers suggested qualifying this->
dependent template name (which indeed way go when referring such dependent members). however, there seems issue, i'll list minimal example reproduces problem.
consider code:
#include <iostream> #include <bitset> using namespace std; template<class t> struct b { t bitset{}; }; template<class t> struct d : b<t> { bool foo() { return this->bitset < 32; } }; int main(){}
the perplexing thing though this->bitset
should refer member b<t>::bitset
, compiler still confused , believes try refer std::bitset<std::size_t>
. error appears on both gcc6 , clang3.7. ideas why happens? qualifying b<t>::bitset
works though.
error (verbatim):
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>'
edit
this looks me parsing/name lookup bug. if replace <
other comparison operator (thanks @leon remark), e.g.
return this->bitset == 32;
the program compiles. guess in this->bitset < 32
parser believes trying instantiate template (the <
sign), , forgot close >
. again have no idea if indeed bug or that's how language suppose work.
tl;dr looks deliberate decision, support alternate syntax used.
an approximate walkthrough of standardese below:
this-> b < ^
- this either start of template id or less-than, let's check both!
this->b
name something, it's templateb<t>
, keep goingb
on it's own names something, class templateb<t>
- wait, they're same thing! means we're using
this->b<t>
qualifier, , isn't less-than after all
in other case,
this->bitset
proceeds identically until third step, when realises there 2 different things called bitset
(a template class member , class template), , gives up.
this working draft have lying around, not recent, but:
3.4.5 class member access [basic.lookup.classref ]
1
in class member access expression (5.2.5), if . or -> token followed identifier followed <, identifier must looked determine whether < beginning of template argument list (14.2) or less-than operator. identifier first looked in class of object expression. if identifier not found, looked in context of entire postfix-expression , shall name class template. if lookup in class of object expression finds template, name looked in context of entire postfix-expression and
- if name not found, name found in class of object expression used, otherwise
- if name found in context of entire postfix-expression , not name class template, name found in class of object expression used, otherwise
- if name found class template, shall refer same entity 1 found in class of object expression, otherwise program ill-formed.
so, in expression this->id < ...
, has handle cases id<...
start of template identifier (like this->b<t>::bitset
).
it still checks object first, if this->id
finds template, further steps apply. , in case, this->bitset
presumably considered template still depends on t
, finds conflicting std::bitset
, fails @ third bullet above.
Comments
Post a Comment