Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling template methods in template classes

Tags:

c++

templates

I'm attempting to figure out why some code that I have won't compile and I done a fair bit of reduction an anonymizing to end up with 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 that I use and the names of the variables I get different errors. They are all centered around this line, though:

    return ap->amem<b>();

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

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], I get the following message:

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 (to me, anyway). If I change the name of 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 expression clang and gcc are looking for? Does anyone know how to solve this problem?

If this is a compiler bug (seems doubtful), does anyone know any workarounds that don't involve converting amem into a function with a bool parameter (rather than a template)? I've done this already and I can confirm that this works around the issue, but this is inside a hot loop and the code that is switched on by b is a memory allocation that probably shouldn't be in a hot loop.

like image 541
Arlen Cox Avatar asked Nov 11 '12 23:11

Arlen Cox


People also ask

How do you call a function in a template?

Defining a Function TemplateA function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.

What is function template and class template?

Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.

Can a template be a template parameter?

Templates can be template parameters. In this case, they are called template parameters. The container adaptors std::stack, std::queue, and std::priority_queue use per default a std::deque to hold their arguments, but you can use a different container.

Can template methods be virtual?

No, template member functions cannot be virtual.


1 Answers

Need to add the template keyword:

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

Please read Where and why do I have to put the “template” and “typename” keywords? for an in-depth explanation.

like image 139
Jesse Good Avatar answered Oct 16 '22 18:10

Jesse Good