C ++ boost :: ptr_vector <S>:: проблема итератора - PullRequest
3 голосов
/ 14 июля 2011

У меня есть этот класс:

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);

};

Когда я пытаюсь определить findPolicy или findState с помощью итератора:

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

Определено после класса, компилятор говорит:

error: expected ';' before it;

Даже попытка определить функцию в объявлении класса выдает мне ту же ошибку.Я озадачен, поскольку именно так я до сих пор использовал итераторы boost :: ptr_vector.Единственная вещь, которая, кажется, работает, - это старый добрый старомод:

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

Что мне не хватает?

Ответы [ 3 ]

7 голосов
/ 14 июля 2011
  boost::ptr_vector<S>::iterator it;

Для этого нужно использовать ключевое слово C ++ typename:

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

В противном случае C ++ не знает, что такое ptr_vector<S>::iterator. Это связано с тем, что определение ptr_vector<S> зависит от параметра шаблона S, а значение S не известно во время определения шаблона. Но компилятор должен уметь понимать строку ptr_vector<S>::iterator, не зная точно, что такое S.

Таким образом, компиляторы предполагают, что зависимые имена являются переменными (поэтому статический член ptr_vector<S>); вам нужно использовать typename, чтобы сообщить компилятору, что зависимое имя является типом, а не переменной.

4 голосов
/ 14 июля 2011

Я думаю, вам нужно добавить typename - я думаю, вам нужно:

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

Всякий раз, когда с шаблонами вы видите какую-то ошибку, такую ​​как:

error: expected ';' before it;

Это потому, что тип перед it не рассматривается компилятором как тип, и поэтому необходимо добавить typename.

0 голосов
/ 14 июля 2011

Это не объясняет сообщение об ошибке IMO, но в опубликованном вами коде вы присваиваете переменную boost::ptr_vector<S>::iterator со значением boost::ptr_vector<P>::iterator.

...