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(){} 

live on coliru

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!
    1. this->b name something, it's template b<t>, keep going
    2. b on it's own names something, class template b<t>
    3. 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

Popular posts from this blog

android - Automated my builds -

how to proxy from https to http with lighttpd -

python - Flask migration error -