1

The following example does not compile with error error: expected primary-expression before ‘>’ token. I do not understand why. I'm trying to call a derived CRTP templated method. I'm doing it this way with CRTP because you can't have virtual templated methods.

https://godbolt.org/z/PMfsPM

#include <iostream>
#include <memory>
#include <type_traits>

struct Foo
{
  Foo(int xx, int yy) : x(xx), y(yy) {}
  int x, y;
};
struct Bar
{
  Bar(int xx, int yy, int zz) : x(xx), y(yy), z(zz) {}
  int x, y, z;
};

template<class Derived = void>
class Base
{
public:
  template<class T>
  std::unique_ptr<T> makeTImpl(int x, int y) {
    return std::make_unique<T>(x, y);
  }
  template<class T>
  std::unique_ptr<T> makeT(int x, int y)
  {
    if constexpr (std::is_same_v<Derived, void>) {
      return makeTImpl<T>(x, y);
    } else {
      auto& d = *static_cast<Derived*>(this);
      return d.makeTImpl<T>(x, y); // error: expected primary-expression before ‘>’ token
    }
  }
};

class Derived : public Base<Derived>
{
public:
  Derived(int z) : _z(z) {}

  template<class T>
  std::unique_ptr<T> makeTImpl(int x, int y) {
    return std::make_unique<T>(x, y, _z);
  }
private:
  int _z;
};

int main() {
  Base b;
  b.makeT<Foo>(1, 2);
  Derived d(3);
  d.makeT<Bar>(1, 2);
}
user2183336
  • 706
  • 8
  • 19
  • @JeJo I was mostly looking for 'CRTP templated method overriding call' or something similar. Here's another hit for future searchers! – user2183336 Aug 03 '20 at 21:00

1 Answers1

2

makeTImpl is a function template, and is used in a dependent context. So instead of:

d.makeTImpl<T>(x, y);

you need to write:

d.template makeTImpl<T>(x, y);
//^^^^^^^^

Here's a demo.

See this post for details on which contexts require the template keyword.

cigien
  • 57,834
  • 11
  • 73
  • 112