A scope resolution statement is required to invoke a member function template when the template template exists with the same name

I have a class template that has the same name as a member function template of some classes. Now another function template is created with one of the classes with the corresponding member function template. To call the member function template in this function template, I need to use the template keyword, I understand this and have no problem with this. However, I need to use the scope resolution operator (I just found out what is called) :: to indicate that I mean the member function template, not the class template, and I don’t understand why.

With a lot of boilerplate stuff, let me give an example:

  //class with same name as member function below. //must be class template or error doesn't show up. //also no error if this is a function template instead of class template <class T> struct f { }; struct Base { //function with same name as struct above, //no error if this is not templated template <int N> void f(){} }; //template function that will be instantiated with T=Base. //no error if this is not templated template <class T> void g(T t) { //I understand why template keyword is needed here, //but not why T:: is needed tT::template f<0>(); //t.template f<0>(); gives error. } 

Emerging error (from g ++ - 4.7)

  error: type/value mismatch at argument 1 in template parameter list for 'template<class T> struct f' error: expected a type, got '0' 

It seems that the compiler parses f<0>() in the commented out line (without the region resolution operator), trying to create an instance of an object of type struct f<0> . I do not know why this is done, I thought that he should see from t.template that I am trying to access the template of a member function.

I would like to understand what is happening here, why is T:: needed in this case, other than reassuring the compiler?

There seems to be no problem in MSVC and Clang, so there seems to be a problem with g ++.

+4
source share
2 answers

I think this is due to a two-stage search . Steve Jessop's comments in the answer are especially important.

+1
source

It can work

 template <class T> void g(T t) { tT::template f<0>(); } 
0
source

Source: https://habr.com/ru/post/1480841/


All Articles