2016-10-13 17 views
0

私の質問にすべての関連情報が含まれていないとお詫び申し上げます。コメントしてください、私はそれに応じて修正します。反復子が左辺値として逆参照されない理由

私はMinGWのとgccでWin7の上CLionを使用


私は私は思わピートGoodlifeによってcircular bufferを使用したい私のプロジェクトの大きさのため、循環バッファを使って実験し、boost::circular_bufferに出くわしてきましたただ1つの固体実装のように.hpp

注::私は、Boost dependencies and bcpのおかげで、ブースト依存性を減らす方法を知っています。

しかし、Peteの実装による次の例は、期待通りに動作しません。つまり、std::adjacent_difference(cbuf.begin(),cbuf.end(),df.begin());の結果はが空になります。です。私はその理由を理解し、その行動を修正したいと考えています。次のように出力さ

#include "circular.h" 
#include <iostream> 
#include <algorithm> 

typedef circular_buffer<int> cbuf_type; 

void print_cbuf_contents(cbuf_type &cbuf){ 
    std::cout << "Printing cbuf size(" 
      <<cbuf.size()<<"/"<<cbuf.capacity()<<") contents...\n"; 
    for (size_t n = 0; n < cbuf.size(); ++n) 
    std::cout << " " << n << ": " << cbuf[n] << "\n"; 

    if (!cbuf.empty()) { 
    std::cout << " front()=" << cbuf.front() 
       << ", back()=" << cbuf.back() << "\n"; 
    } else { 
    std::cout << " empty\n"; 
    } 
} 

int main() 
{ 
    cbuf_type cbuf(5); 
    for (int n = 0; n < 3; ++n) cbuf.push_back(n); 
    print_cbuf_contents(cbuf); 

    cbuf_type df(5); 
    std::adjacent_difference(cbuf.begin(),cbuf.end(),df.begin()); 
    print_cbuf_contents(df); 
} 

df.begin()イテレータは左辺値として逆参照されていない理由

Printing cbuf size(3/5) contents... 
    0: 0 
    1: 1 
    2: 2 
    front()=0, back()=2 
Printing cbuf size(0/5) contents... 
    empty 

は残念ながら、Cに新しいもの++私は把握することはできません

はMWEに従います。

私はピートのcircular.hでライン72上のcircular_buffer_iteratorのメンバーコール犯人がsupsect(または完全にuderstandません):

elem_type &operator*() { return (*buf_)[pos_]; }

すべてのヘルプは非常に高く評価されます。

答えて

1

あなたは出力イテレータとして渡すイテレータ逆参照され、左辺値として扱われ、実際には循環バッファのバッファに実際に格納されるデータが格納されます。

問題は、実際のストレージバッファとは別に、 (例えば、バッファ内にいくつの要素があるか、空き領域がどれだけ空いているかなど)

コンテナの参照解除と増分は内部状態を更新しないため、コンテナは新しいデータが追加されたことを「認識」しません。

std::vector<int> v; 
v.reserve(3); 

auto i = v.begin(); 
*(i++) = 1; // this simply writes to memory 
*(i++) = 2; // but doesn't update the internal 
*(i++) = 3; // state of the vector 
assert(v.size() == 0); // so the vector still "thinks" it's empty 

期待通りに機能するであろう一backを使用した:

あなたのケースでは
std::vector<int> v; 
v.reserve(3); 

v.push_back(1); // adds to the storage AND updates internal state 
v.push_back(2); 
v.push_back(3); 

assert(v.size() == 3); // so the vector "knows" it has 3 elements 

、あなたがのstd :: back_inserter、上の "一back" を呼び出すイテレータを使用する必要があります

は、次のコードを考えてみましょう逆参照されるたびにコンテナ:

std::adjacent_difference(
    cbuf.begin(), cbuf.end(), 
    std::back_inserter(df)); 
+0

PeteのコンテナはSTLに準拠していると主張しているので、 'adjacent_difference() 'のこの[example](http://en.cppreference.com/w/cpp/algorithm/adjacent_difference#Example) 'ベクトル上にある。状態の更新をトリガするためにどのような調整を導入する必要がありますか? – Oleg

+0

私は、[this post]の 'back_inserter()'についてもう少し詳しく読むことを理解し始めていると思います。(http://stackoverflow.com/questions/27215748/what-happens-if-i-use-vectorbegin- stdback-insertervector-forの代わりに)、これは基本的に私の使用事例を説明しています。しかし、私はcppreferenceがそのような例を含む理由は不明です... – Oleg

0

std::adjacent_difference結果イテレータに書き込みます。あなたのケースでは、その結果反復子はdfを指します。サイズは0で、容量は5です。これらの書き込みは予約されたメモリdfになりますが、コンテナのサイズは変更されません。 0であり、予約されたコンテナスペースの最初の3つのintはあなたの違いを持っ​​ています。結果を見るためには、書き込まれているコンテナには、既に書き込まれているスロットに格納されているデータがなければなりません。 adjacent_differenceで返される反復子に基づいて、

それでは、適切な大きさに、コンテナのサイズを変更し、あなたが違い前に、循環バッファにデータを置く必要があり、結果を見るために(。

+0

これはダブル作業のように聞こえ、 'df'を入力して上書きしますそれら。 boost :: circular_bufferが何をしていたのか分からないが、私はこの問題を抱えていなかった。 – Oleg

関連する問題