2016-04-01 3 views
0

Я вывожу вектор класса stl vector и пытаюсь перегрузить операторы [], чтобы обеспечить проверку диапазона доступа к элементу с индексом. Но я получаю ошибки компиляции при попытке создать объект const моего производного класса Vec.не удалось создать объект const класса, полученный из std :: vector

В приведенном ниже примере это код:

template<class T> 
class Vec : public vector<T> 
{ 
    public: 
    Vec(): vector<T>() 
    { 
    } 
    Vec(int i):vector<T>(i) 
    { 
    } 
    T& operator[](int i) 
    { 
     return at(i); 
    } 
    const T& operator[](int i) const 
    { 
     if(i>=size()) 
     cout<<"error"<<endl; 
     return at(i); 
    } 
}; 

void main() 
{ 
    Vec<int> v1(10); //works fine 
    const Vec<int> v(10); //error         
} 

Почему код Const вектор v (10); работает, но const Vec v1 (10); не работает. Есть ли что-то, что мне не хватает? Почему я не могу создать объект const?

+1

Сделайте нам одолжение и разместите свой * настоящий * код. Ошибка, которую вы описываете, если она находится в этой публикации, затмевается многочисленными другими ошибками. – WhozCraig

+2

Я, к сожалению, не могу воспроизвести вашу проблему с g ++ 4.5 (после устранения таких проблем, как 'void main', missing includes, а также не квалифицирующих независимых имен с' this-> '). Можете ли вы предложить дополнительные разъяснения, чтобы помочь нам? –

+0

@MarkB так же это. – WhozCraig

ответ

0

Классы STL, такие как std::vector, как правило, не должны быть получены.

Но код корректно работает так:

template<class T> 
class Vec : public vector<T> 
{ 
    public: 
    Vec(): vector<T>() 
    { 
    } 
    Vec(int i):vector<T>(i) 
    { 
    } 
    T& operator[](int i) 
    { 
     return vector<T>::at(i); 
    } 
    const T& operator[](int i) const 
    { 
     if(i>=vector<T>::size()) 
     cout<<"error"<<endl; 
     return vector<T>::at(i); 
    } 
}; 

int main() 
{ 
    Vec<int> v1(10); //works fine 
    const Vec<int> v(10); //error         
    v1.push_back(5); 
    v1.push_back(6); 
    int i = v1[3]; 
} 

Функция at и size от необходимости базового std::vector быть вызваны с использованием либо vector<T>::at(i) или this->at(i). Это всегда верно, когда базовый класс является шаблоном: тогда «vector<T>» является зависимым именем (его значение зависит от аргумента шаблона T), и в этом случае его члены не будут автоматически экспортированы в область определения класса Vec ,

Также cout<"error" должен быть cout<<"error", а main должен вернуть int.

const не представляет проблемы в этом случае.

В общем, push_back не может использоваться на const std::vector, так как он изменяет вектор. Но инициализация копирования или инициализация списка могут использоваться для создания непустого const std::vector. Например

const std::vector<int> vec {1, 2, 3}; 
0

Bjarne Stroustrup охватывает этот вопрос в разделе «Экскурсия по C++».

template<typename T> 
class Vec : public std::vector<T> { 
public: 
    using vector<T>::vector;  // use the constructors from vector (under the name Vec) 

    T& operator[](int i) 
    { return vector<T>::at(i); } 

    const T& operator[](int i) const 
    { return vector<T>::at(i); } 
} 

«Vec наследует все от вектора для операций индексного что переопределяет делать проверку диапазона, за исключением.»

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