Search code examples
c++boost-iterators

C++ boost::ptr_vector<S>::iterator problem


I have this class:

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

    timeval start;
    boost::ptr_vector<S> states;
    boost::ptr_vector<P> policies;

  public:

    P findPolicy(S *state);
    S findState(S *state);

};

When I try to define findPolicy or findState using an iterator:

template <class S, class P, class A>
S Task<S,P,A>::findState(S *state)
{
  boost::ptr_vector<S>::iterator it;
  for ( it = policies.begin(); it < policies.end(); ++it)
  {
    // blah 
  }
}

Defined after the class, compiler says:

error: expected ';' before it;

Even trying to define the function in the class declaration gives me the same error. I'm puzzled since this is how I've been using boost::ptr_vector iterators so far. The only thing that seems to work is good old fashioned:

for (int i = 0; i < policies.size(); i++)
  {
    if (policies[i].getState() == state)
    {
     return policies[i];
    }
  }

What am I missing ?


Solution

  •   boost::ptr_vector<S>::iterator it;
    

    This needs to use the C++ keyword typename:

    typename boost::ptr_vector<S>::iterator it;
    

    Otherwise, C++ doesn't know what ptr_vector<S>::iterator is supposed to be. This is because the definition of ptr_vector<S> depends on the template parameter S, and the value of S is not known at the time of the template's definition. But the compiler needs to be able to make sense of the line ptr_vector<S>::iterator without knowing what S is exactly.

    So compilers assume that dependent names are variables (so a static member of ptr_vector<S>); you need to use typename in order to tell the compiler that the dependent name is a type and not a variable.