2016-04-01 13 views
0

stlコンテナクラスベクトルを派生し、[]演算子をオーバーロードして要素にアクセスする際の範囲チェックを下付き文字で実行しようとしています。 しかし、派生クラスVecのconstオブジェクトを作成しようとすると、コンパイルエラーが発生します。以下例えばstd :: vectorから派生したクラスのconstオブジェクトを作成できません

コードである:

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が含まれていて、' this-> 'で依存しない名前を修飾しないでください)。あなたは私たちを助けるためにどんな詳細な説明もしていただけますか? –

+0

@マークBもそうです。 – WhozCraig

答えて

0

std::vectorのようなSTLクラスは、一般に、派生するものではありません。

しかし、コードは次のように正しく動作:

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

機能atsizevector<T>::at(i)またはthis->at(i)のいずれかを使用して呼び出されるベースstd::vector必要性から。 "vector<T>"は依存名(その意味はテンプレート引数Tによって異なります)の場合、そのメンバーは自動的にVecクラス定義のスコープにエクスポートされません。

cout<"error"cout<<"error"で、mainintを返す必要があります。

constこの場合、問題はありません。

一般に、push_backは、ベクターを改変するため、const std::vectorには使用できません。しかし、コピーの初期化またはリストの初期化を使用して、空でないconst std::vectorを作成することができます。例えば、

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

Bjarne Stroustrupは「A Tour of 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とは、範囲チェックを行うために再定義することを、ベクターからの添字操作用以外のすべてを継承します。」

関連する問題