2017-08-17 17 views
0

私は線形代数、特にベクトルと行列のクラスを持っています。これらは、とりわけstd :: vectors(またはstd :: maps)を 'data'フィールドとして含みます。C++ STL; STLコンテナを含むクラスを反復するか?

これらをループに基づいた範囲で反復するのは簡単です。しかし、私はこれらのフィールドを非公開にして、私のカスタムクラスをより自然に反復するようにして、クラスそのもののループに基づく範囲を行うことができます。

std :: vector <> .begin()などの関数定義を見てみました。次に、すべてのイテレータオブジェクトがstd :: vector <>フィールドからforwadされるように実装しようとしましたが、役に立たなくなりました。次の例では、クラスの定数インスタンスを繰り返し処理しようとしています。

int main() { 

    AlgebraLib::Vector A(4, true); 
    A[0] = 4; 
    A[1] = 5; 
    A[2] = 6; 
    A[3] = 7; 

    for (auto &&item : A) { 
     std::cout << item << std::endl; 
    } 

    const AlgebraLib::Vector B = A; 

    for (auto &&item : B) { 
     std::cout << item << std::endl; 
    } 

    return EXIT_SUCCESS; 
} 

...次のコンパイラエラーが発生します。

error: passing ‘const AlgebraLib::Vector’ as ‘this’ argument discards qualifiers [-fpermissive] 
for (auto &&item : B) { 

基本的に、すべてのイテレータは、次のように定義されています。私はここで何かが欠けてるように私は感じ

// Iterators 
    std::vector<double>::iterator begin(); 

    std::vector<double>::iterator end(); 

    std::vector<double>::reverse_iterator rbegin(); 

    std::vector<double>::reverse_iterator rend(); 

    std::vector<double>::const_iterator cbegin() const noexcept; 

    std::vector<double>::const_iterator cend() const noexcept; 

    std::vector<double>::const_reverse_iterator crbegin() const noexcept; 

    std::vector<double>::const_reverse_iterator crend() const noexcept; 

std::vector<double>::iterator Vector::begin() { 
    return _VectorContents.begin(); 
} 

std::vector<double>::iterator Vector::end() { 
    return _VectorContents.end(); 
} 

std::vector<double>::reverse_iterator Vector::rbegin() { 
    return _VectorContents.rbegin(); 
} 

std::vector<double>::reverse_iterator Vector::rend() { 
    return _VectorContents.rend(); 
} 

std::vector<double>::const_iterator Vector::cbegin() const noexcept{ 
    return _VectorContents.cbegin(); 
} 

std::vector<double>::const_iterator Vector::cend() const noexcept{ 
    return _VectorContents.cend(); 
} 

std::vector<double>::const_reverse_iterator Vector::crbegin() const noexcept{ 
    return _VectorContents.crbegin(); 
} 

std::vector<double>::const_reverse_iterator Vector::crend() const noexcept{ 
    return _VectorContents.crend(); 
} 

そして、私のヘッダーVector.hppで?私はC++に比較的新しいです。私は現時点でC++ 11で作業しています。

+0

「行」とは何ですか? '_VectorContents'とは何ですか?私たちを表示するには、[最小、完全で、検証可能な例](http://stackoverflow.com/help/mcve)を作成してください。 –

+1

関連のない注記では、アンダースコアで始まり、大文字の後に続くすべてのシンボル(たとえば、_VectorContents)はすべてのスコープで予約されています。詳細については、[この古い質問とその回答](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier)を参照してください。 –

+0

申し訳ありませんが、より良い例を作りました。そしてアンダースコアのコメントをありがとう、私は実際にすべてのメンバー変数のためにそれを使用しました。 –

答えて

1

問題はBconstであるということですが、レンジのためのループが唯一beginend(ないcbegincend)を使用し、あなたのbeginend機能がconstある何の過負荷を持っていません。これは、constとしてマークされた関数だけがconstオブジェクトで呼び出されるため、問題です。

解決策は単純です:ちょうどこれらのオーバーロードの実装は非const関数の場合と全く同じになります

std::vector<double>::const_iterator begin() const; 

std::vector<double>::const_iterator end() const; 

、このようなオーバーロードを追加します。

関連する問題