Calling template methods in template classes

I am trying to understand why some of the code that I have will not compile, and I did a small part of the reduction for anonymity to complete this example:

#define NULL ((void*)0) template<typename T> class a { public: template<bool b> T * amem() { return NULL; } }; template<typename T> class b { public: a<T>* ap; template <bool b> T * m() { return ap->amem<b>(); } }; int main() { return 0; } 

Depending on the compiler used and the variable names, I get different errors. They are all centered around this line:

  return ap->amem<b>(); 

Compiling using clang ++ [Apple clang version 4.0 (tags / Apple / clang-421.0.57) (based on LLVM 3.1svn)], the following message appears:

 tmp.cpp:18:26: error: expected expression return ap->amem<b>(); ^ 1 error generated. 

Compiling using g ++ [i686-apple-darwin11-llvm-g ++ - 4.2 (GCC) 4.2.1], the following message appears:

 tmp.cpp: In member function 'T* b<T>::m()': tmp.cpp:18: error: expected primary-expression before '>' token tmp.cpp:18: error: expected primary-expression before ')' token 

Mysteriously (for me, anyway). If I change the name amem to m, I no longer get any errors from g ++, but I get the same error from clang ++.

I'm sure there is something here that I just don’t understand? Does anyone know what clang and gcc expression are looking for? Does anyone know how to solve this problem?

If this is a compiler error (seems doubtful), does anyone know of workarounds that are not related to converting amem into a function with a bool parameter (and not a template)? I have already done this, and I can confirm that this works around the problem, but it is inside the hot loop, and the code that b is on is the memory allocation, which probably should not be in the hot loop.

+4
source share
2 answers

You must add the template keyword:

 return ap->template amem<b>(); 

Please read Where and why should I put the keywords "template" and "typename"? for a detailed explanation.

+18
source

In the context in which you invoke

 return ap->amem<b>(); 

the name amem is a dependent name: if such a beast really refers to a member function template, you need to say this by adding the template keyword:

 return ap->template amem<b>(); 

By the way, note that it should not define NULL ! If you need an abomination definition, you must include, for example, cstddef . It is best to use only 0 or nullptr when using C ++ 2011.

+3
source

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


All Articles