1

多項式の係数を表すためにstd :: vectorの周りに小さなラッパークラスを作成しようとしています。呼び出し元は係数を反復処理できる必要がありますが、基本的な実装を公開したくありません。パターンを使用両方のメソッドが利用可能であっても、コンパイラはVector_const_iteratorとVector_iteratorを "変換"できません

herehereを説明し、他の場所で、私は以下のようにイテレータに沿って通過するように試みた:

typedef std::vector<unsigned char> charVec; 

class gf255_poly 
{ 
    public: 

     // Constructors and Polynomial-y Functions 

     // ... 

     // Iterators to go from high to low degree 

     charVec::const_reverse_iterator h2l_begin() const { return p.rbegin(); }; 
     charVec::const_reverse_iterator h2l_end() const { return p.rend(); }; 
     charVec::reverse_iterator  h2l_begin() { return p.rbegin(); }; 
     charVec::reverse_iterator  h2l_end() { return p.rend(); }; 

     // Iterators to go from low to high degree 

     charVec::const_iterator l2h_begin() const { return p.begin(); }; 
     charVec::const_iterator l2h_end() const { return p.end(); }; 
     charVec::iterator  l2h_begin() { return p.begin(); }; 
     charVec::iterator  l2h_end() { return p.end(); }; 

    protected: 
     std::vector<unsigned char> p; 
}; 

これらgf255_polyオブジェクトは、その後、このいずれかのような方法に慣れます

// Performs polynomial evaluation in GF(2^8) 
unsigned char gf255_poly_eval(const gf255_poly &poly, unsigned char x) const 
{ 
    unsigned char fx = poly.coefHigh(); // Initialize with coef of highest degree term 

    // Use Horner's method with consecutively factored terms: 
    // x^3 + 2x^2 + 3x + 4 -> (((1x + 2)x + 3)x + 4) 

    charVec::reverse_iterator next_coef; 

    for (next_coef = poly.h2l_begin(); next_coef != poly.h2l_end(); next_coef++) 
     fx = gf255_mul(fx, x)^*next_coef; // Recall^is addition in GF 2^8 

    return fx; 
} 

シンプルですが、タイプに問題があります。 Visual Studioは私がパズルのように見えることができないためのループ、との行に私は、このエラーを与える:

error C2664: 'std::_Revranit<_RanIt,_Base>::_Revranit(_RanIt)' : cannot convert parameter 1 from 'std::_Vector_const_iterator<_Ty,_Alloc>' to 'std::_Vector_iterator<_Ty,_Alloc>' 

私はこのメッセージを理解していない - 私は両方のイテレータを返すメソッドを提供してきましたし、 const_iterators。なぜコンパイラはそれらの間で選択できないのですか?この質問で暗黙


が、これは(彼らはまだこれらのstd ::ベクトルの種類に対処する必要があるため)、すべての発信者から詳細を隠すための良い戦略があるかどうかである、と私は答えをいただければ幸いいますこれにも対処してください。

答えて

1
charVec::reverse_iterator next_coef = poly.h2l_begin(); 

next_coefreverse_iteratorです。 h2l_begin()は何を返しますか?

まあ、polyは次のとおりです。

const gf255_poly &poly 

const gf255_poly。だから、私たちはh2l_begin()のオーバーライドを見てみましょう:

charVec::const_reverse_iterator h2l_begin() const { return p.rbegin(); }; 
charVec::reverse_iterator  h2l_begin() { return p.rbegin(); }; 

は、2つのオーバーロードがあります。

charVec::const_reverse_iterator h2l_begin() const { return p.rbegin(); }; 

のでpoly.h2l_begin()戻りcharVec::const_reverse_iteratorpolyconstあり、そしてそれは、この1であるので、一つだけは、有効です。 charVec::reverse_iteratorはそうではないcharVec::const_reverse_iteratorは、あなたが繰り返し処理されたものを変更することができますので、

charVec::const_reverse_iteratorは、charVec::reverse_iteratorに変換することはできません。

つまり、polyconstなので、あなたはそれを変更しないと約束しています。そして、それを変更する可能性のある型を使用してそれを繰り返しました。だからタイプエラーが出ます。

第2に、コンパイラは、戻り値の型(おそらく変換operator T()を除く)に基づいて関数間で決して選択しないことに注意してください。 にpoly以外の定数を格納している場合は、reverse_iterator h2l_begin()と表示されます。 reverse_iteratorconst_reverse_iteratorに変換されます。


最初に行うべきことは、C++ 11にアップグレードすることです。この2016年

第二に、私はなど、sizeIteratoroperator[]のランダム・アクセス・ネスに基づいてイテレータの範囲を格納し、beginendを公開し、条件付き(range_t<Iterator>を記述します。またremove_front(size_t)front()emptyと...

それからT* C::data()方法、生C-配列、およびT*, size_tと容器からの暗黙ctorsと連続T sの範囲を表すarray_view<T>:range_it<T*>を書き込みたい。

最後に、backwards_tbackwardsという関数を書くと、range_t<Iterator>を返し、range_t< reverse_iterator<Iterator> >を返します。

今私のgf255_polyは、これらの持っている:私たちが選択した場合、我々はイテレータのためのtypedefを公開することができ

backwards_t< array_view< unsigned char > > h2l(); 
backwards_t< array_view< unsigned char const > > h2l() const; 
array_view< unsigned char > l2h(); 
array_view< unsigned char const > l2h() const; 

(およびC++ 03で、私たちは選択の余地があります)。 C++ 11では

それは次のようになります。素敵である

for (auto&& next_coef = poly.h2l()) 
    fx = gf255_mul(fx, x)^next_coef; // Recall^is addition in GF 2^8 

charVec::reverse_iterator next_coef; 

これに:この

+0

、C++ 11 ISN」を現在のところオプションです。デベロッパーの皆さんはVSへのアップグレードを希望していますが、実際には起こるという兆候はありません。それでも、新しい機能を追求するための徹底的な答えと弾薬に感謝します! – Bear

1

polyはconstオブジェクトなので、h2l_begin()はconst_reverse_iteratorを返します。 next_coefreverse_iteratorと宣言しましたが、イテレータにconstイテレータを割り当てることはできません。 next_coefconst_reverse_iteratorに変更するか、forループでautoを指定して宣言してください。

for (auto next_coef = poly.h2l_begin(); next_coef != poly.h2l_end(); ++next_coef) 
0

変更

charVec::const_reverse_iterator next_coef; 

あなたは以下を参照してくださいpolygf255_polyオブジェクトへconst参照され、そのconst資格のバージョンを好むでしょうpoly.h2l_begin();の要求を意味過負荷解決時に機能します。それでもループ初期化のために外にイテレータを保つ必要がある場合は

まだよく、auto

for (auto next_coef = poly.h2l_begin(); next_coef != poly.h2l_end(); next_coef++) 
    fx = gf255_mul(fx, x)^*next_coef; // Recall^is addition in GF 2^8 

を使用し、あなたは外intitializationを移動することができます。残念ながら

auto next_coef = poly.h2l_begin() 
for (; next_coef != poly.h2l_end(); next_coef++) 
    fx = gf255_mul(fx, x)^*next_coef; // Recall^is addition in GF 2^8 
関連する問題