Ælex
Ælex

Reputation: 14869

C++ template class Type being forwarded as parameter to object's template function

Ok, I don't know if the title made much sense, so I will just show the code:

template <class S,class P,class A> class Task
{
  protected:

    timeval start;
    boost::ptr_vector<S> states;
    boost::ptr_vector<P> policies;
    Agent &robot;
    const ACTION_MODE &a_mode;
    A algo;

  public:

    Task(Agent &a, ACTION_MODE &m, A &alg) : robot(a), a_mode(m), algo(alg) {};
    P* findPolicy(S *state);
    bool stateExists(S *state);
    bool if_appendState(S *state);
    bool policyExists(P *policy);
    bool if_appendPolicy(P *policy);  
    void run();
};

Class S, is for States (a polymorphic class ) class P is for policies (a templated polymoprhic class) and class A is for Algorithm classes. For example (a class A - type):

class SarsaTD
{
  protected:
    const float gamma;
    const float alpha;
    PTYPE method;
  public:
    SarsaTD(float a, float g) : alpha (a), gamma (g) {method = ON_POLICY; };
    template <typename P> void optimize(P *policy);
    PTYPE getType();
};

I am trying to use from class Task's parameter P (policies) and forward it into a method of an instance of SarsaTD.

template <class S,class P,class A> void Task<S,P,A>::run()
{
  S *state = new S(Task<S,P,A>::robot, const_cast<ACTION_MODE&>(Task<S,P,A>::a_mode));
  P *policy;
  if (Task<S,P,A>::if_appendState(state))
  {
    policy = new P(state);
    Task<S,P,A>::if_appendPolicy(policy);
  }
  else
  {
    policy = Task<S,P,A>::findPolicy(const_cast<S *>(state));
    policy->getValue();
    delete state;
  }

  Task<S,P,A>::algo.optimize<P>(policy);
  wb_robot_step(TIME_STEP);
}

Everythign works fine, untill the line: Task<S,P,A>::algo.optimize<P>(policy); Where the compiler gives the following error:

task.hpp:174: error: expected-primary expression before '>'token

If I understand this correctly, the Parameter type P (policy) I use throughout the template class cannot be forwarded properly into the template function ? Or is my syntax wrong ? Or what I am trying to do simply makes no sense ?

Upvotes: 2

Views: 372

Answers (2)

Sebastian Mach
Sebastian Mach

Reputation: 39099

Task<S,P,A>::algo.optimize<P>(policy);

At that point it can't know whether optimize is a value or not. You'll understand if you just look at

Task<S,P,A>::algo.optimize < P

This not only looks like a comparison to you, but also to the compiler. Even if it then proceeds with parsing, it can't know whether your intention was a comparison or a template argument list, unless it fully instantiates the template type. If you search for "dependent name" and "two phase lookup", you'll find some useful information. The solution in your case would be manual disambiguation. Tell the compiler that optimize is a template:

Task<S,P,A>::algo.template optimize<P>(policy);

Upvotes: 4

Jaffa
Jaffa

Reputation: 12719

You use a template parameter in another part of the expression, try to do :

Task<S, P, A>::algo.template optimize<P>(policy)

This should work like that.

Upvotes: 2

Related Questions