2009-04-07 4 views
1

Следующий фрагмент коды отвечает за скрытую ошибку компилятора MSVC++:MSVC++ Ошибка компилятора C2143

template<class T> class Vec : public vector<T>{ 
    public: 
    Vec() : vector<T>(){} 
    Vec(int s) : vector<T>(s){} 

    T& operator[](int i){return at(i); } 
    const T& operator[](int i)const{ return at(i);} 
}; 

... 

Ошибка:

test.cpp(5) : error C2143: syntax error : missing ',' before '<' 
    test.cpp(12) : see reference to class template instantiation 'Vec<T>' being compiled 

Как это исправить?

--- Edit ---

Некоторые контекст:

Я пытаюсь скомпилировать код по существу скопировать и вставить из программирования C++ Language. Я еще не совсем понимаю этот код. Целью, однако, является реализация векторного типа, который генерирует исключение, когда какой-либо код пытается получить доступ к элементу из диапазона вектора вместо того, чтобы просто возвращать неверные значения.

+0

Показать пожалуйста создание экземпляра Vec – bayda

+0

Ваш класс довольно бессмыслен. По умолчанию оператор [] в MSVC также выполняет проверку границ, как и at(). Таким образом, вы на самом деле не добавляете ничего нового в класс, только вводите потенциальные ошибки (см. Ответ JaredPar). – jalf

ответ

1

Почему вы пытаетесь наследовать от вектора? Это вызовет у вас массу проблем. Наименьшим из них является то, что вектор не имеет виртуального деструктора. Это приведет к вызову неправильного деструктора при удалении полиморфной ссылки на ваш класс, что приведет к утечке памяти или вообще к плохому поведению.

Например, следующий код не будет вызывать ~ Vec(), но вместо этого вызовет ~ vector().

vector<int> *pVec = new Vec<int>(); 
delete pVec; // Calls ~vector<T>(); 

Фактическая ошибка компиляции вы видите, хотя это потому, что вы используете синтаксис шаблона для вызова базового конструктора. Просто удалить, что и он должен составить

Vec() : vector() {} 
+0

+1. Вы правы, чтобы предупреждать о неполиморфном делеции, но OTOH, любой код, который динамически выделяет векторы, в любом случае является подозрительным. (Единственная причина, по которой я могу думать о динамическом распределении чего-то, - это когда вы не знаете его размер до времени исполнения, но размер вектора может меняться в любом случае.) –

+0

Основная причина для динамического выделения чего-либо состоит в том, что вы не знаете, сколько элементов у вас есть до выполнения, или каковы их фактические типы. – 2009-04-07 16:31:05

+1

@Neil: Хорошая точка в общем, но в конкретном случае векторов: (1) Не знаю, сколько: безопаснее использовать вектор векторов, чем динамически выделять массив векторов с новыми; (2) Не зная фактических типов: не зная точного типа вектора, который вы хотите, запах, как overdesign для меня. –

3

Попробуйте

template<class T> class Vec : public vector<T>{ 
    public: 
    Vec() : vector(){} // no <T> 
    Vec(int s) : vector(s){} // same 

    T& operator[](int i){return at(i); } 
    const T& operator[](int i)const{ return at(i);} 
}; 

Конструктор для шаблона класса не включает шаблон подписи в его названии.

Как примечание стороны, ваш второй конструктор должен быть действительно

Vec(typename vector<T>::size_type s) : vector(s){} // not necessarily int 

Наконец, вы действительно не должны извлечь из вектора, так как она имеет не виртуальный деструктор. Не пытайтесь удалить Vec через указатель на вектор.

+0

Собственно, вторым конструктором должен быть Vec (size_type s). Это число элементов в векторе, а не элемент, который нужно поместить в вектор. –

+0

size_type >> size_t –

+1

@ Benoît: Не обязательно. std :: vector определяет size_type, который может быть или не быть таким же, как size_t. –

0

От MSDN: Compiler Error C2143 (C++)

An unqualified call is made to a type in the Standard C++ Library:
// C2143g.cpp 
// compile with: /EHsc /c 
#include <vector> 
static vector<char> bad; // C2143 
static std::vector<char> good; // OK 

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

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