3

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 ?

Ælex
  • 14,432
  • 20
  • 88
  • 129

3 Answers3

7
  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.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • @Alex: The problem is that `boost::ptr_vector` is dependent on template parameter `S` and so the compiler has no way of knowing whether it is a type or a value. When such an ambiguity arises, it assumes it is value, which then leads to compilation errors. Qualifying the declaration with the `typename` keyword tells the compiler to treat it as a dependent type. – Praetorian Jul 14 '11 at 07:36
4

I think you need to add typename - I think you need:

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

Whenever with templates you see some error like:

error: expected ';' before it;

It is because the type in front of it is not being seen by the compiler as a type and so one needs to add a typename.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
0

It doesn't explain the error message IMO, but in the code you posted you assign a boost::ptr_vector<S>::iterator variable with a boost::ptr_vector<P>::iterator value.

themel
  • 8,825
  • 2
  • 32
  • 31
  • @Alex - In `findState` you use a `vector::iterator` when `policies` is a `vector

    `. Of course this depends on the actual S and P, so sometimes it might be ok.

    – Bo Persson Jul 14 '11 at 07:49