2013-08-27 4 views
0

Не могли бы вы указать на то, что не так со следующим классом шаблонов?Visual C++ 2012: компилятор жалуется на «missing»; «

#include <vector> 

template <typename T, typename C> 
struct pQueue{ 
    pQueue():currEnd(c.end()){}; 
    ~pQueue(){c.~vector();} 
    void insert(T& t); 
    void remove(T& t); 
    bool find(T& t); 
    T head(void); 
private: 
    std::vector<T> c; 
    std::vector<T>::iterator currEnd; 
}; 

Компилятор не очень рад о std::vector<T>::iterator currEnd; линии, и выдает следующие сообщения об ошибках:

ошибка C2146: синтаксическая ошибка: отсутствует «;» перед идентификатором 'currEnd'

ошибка C4430: отсутствует спецификатор типа - int. Примечание: C++ не поддерживает default-int

Большое спасибо!

+0

[Релевантно] (http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords). Кстати, GCC и Clang дают для этого чрезвычайно простые ошибки. – chris

+0

К счастью, gcc предлагает решение: http://ideone.com/tUQz2B – mfontanini

+3

Не связано с ошибками, но вы явно вызываете деструктор из '~ pQueue()'. Зачем? Поскольку 'c' является фактическим вектором, а не указателем, его деструктор будет работать в любом случае. –

ответ

3

компилятор не признает std::vector<T>::iterator как тип. Вы должны сказать ему:

typename std::vector<T>::iterator currEnd; 

typename используется как disambiguitator в шаблонных контексте. Он просто сообщает компилятору, что идентификатор std::vector<T>::iterator является типом, а не статическим членом. Стандарт требует этого в шаблоном контексте, хотя в большинстве случаев компилятор может работать так, даже если параметр шаблона T не указан.


В то время как вышеприведенный ответ на ваш вопрос, я могу только подчеркнуть, что juanchopanza указал на ваш код. Кроме того, для вас уже есть std::queue.

+0

Он действительно компилируется. Но что именно делает ключевое слово «typename» в этом контексте? – user2531913

+0

@ user2531913 Сообщает компилятору, что вектор :: iterator - это тип, а не статическая переменная-член. –

+0

Это приоритетная очередь. Я могу использовать priority_queue, но я не могу понять, как это сделать; Я также могу использовать std :: set, но я предполагаю, что я предпочел бы реализовать собственный сам, что делает именно то, что должна делать очередь приоритетов. – user2531913

1

Вы должны сказать компилятору итератор является именем типа, потому что это зависит имя:

typename std::vector<T>::iterator currEnd; 

Кроме того, этот класс не нужен предоставленный пользователем деструктор. Ваше определение класса может быть упрощена следующим образом:

template <typename T> 
struct pQueue 
{ 
    pQueue() : currEnd(c.end()) {}; 
    void insert(const T& t); 
    void remove(const T& t); 
    bool find(const T& t); // this should probably be a const method 
    T head();    // this should probably be a const method 
private: 
    std::vector<T> c; 
    typename std::vector<T>::iterator currEnd; 
}; 
+0

Я хочу использовать std :: remove, чтобы я мог извлекать вещи из очереди приоритетов, фактически не освобождая их, отслеживая, где на самом деле находится конец очереди. Спасибо за указание на consts, я добавил их. – user2531913

+0

@ user2531913 О, я вижу, поэтому вы сохраняете итератор «end», который не обязательно является концом 'c'? Я думаю, что однажды я мог бы сделать что-то подобное с очередью ... – juanchopanza

+0

yep. Это правильно – user2531913

0

Я думаю, что это должно быть typename std::vector<T>::iterator currEnd;.

Затем compilcater составитель компилятор может выяснить, что iterator на самом деле тип и не является членом (из std::vector).

+3

Визуальный студийный компилятор действительно «сложный» :) – user1233963

0

Просто путем добавления к другим ответам:

К сожалению, VisualStudio не очень хорошие сообщения об ошибках. Вы в значительной степени должны узнать, что они означают, а не читать их буквально. Например:

missing ';' before identifier 'currEnd'

ли VisualStudio-ESE обычно означает "я не знаю, что идентификатор, прежде чем currEnd есть." Обычно это связано с тем, что в этот момент это не определено. 9 раз из 10, это будет имя типа/класса для типа/класса, на которое вы пренебрегли #include заголовком. В этом случае похоже, что речь идет скорее о компиляторе, запутанном с использованием шаблона в шаблоне.

Однако принцип стоит. Если бы вы начали с: «Компилятор не знает, что такое тип/класс до currEnd.», Вы были бы на правильном пути.

Смежные вопросы