2016-10-13 11 views
0

내 질문에 관련 정보가 모두 포함되어 있지 않은 경우 사과드립니다. 의견을 말하면 그에 따라 개정 할 것입니다.iterator가 lvalue로 역 참조되지 않는 이유

내가는 MinGW와 GCC와 Win7에에 CLion를 사용


난하지만 난 것 같다 피트 Goodlife에 의해 circular buffer를 사용하려면 내 프로젝트의 크기, 원형 버퍼 실험 및 boost::circular_buffer 건너 온 한 단 한 번의 구현으로 단 한 번의 구현처럼 .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

가 출력 반복자로 전달할 반복자 역 참조되고 lvalue로 취급되며 예상되는 데이터는 원형 버퍼의 버퍼에 실제로 저장됩니다.

실제 저장소 버퍼를 제외하면 대부분의 컨테이너에는 내부 장부 보관 상태가 포함되어 있습니다. (예 : 버퍼에 몇 개의 요소가 있는지, 얼마나 많은 공간이 남아 있는지 등)

컨테이너를 역 참조 및 증가시키지 않아도 내부 상태가 업데이트되지 않으므로 컨테이너는 새 데이터가 추가되었음을 "알지 못합니다".

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 

예상대로 작동 것와 push_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 

, 당신이 표준 : back_inserter에 "와 push_back"을 호출하는 반복자를 사용한다

다음 코드를 고려 컨테이너가 참조 해제 될 때마다 :

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

문제는 Pete의 컨테이너가 STL 규격이라고 주장하고 있으며 인접한 차이점()의 [예제] (http://en.cppreference.com/w/cpp/algorithm/adjacent_difference#Example)처럼 동작 할 것으로 기대합니다. '벡터에. 상태 업데이트를 트리거하기 위해 어떤 조정을해야합니까? – Oleg

+0

[this post] (http://stackoverflow.com/questions/27215748/what-happens-if-i-use-vectorbegin-)에서'back_inserter()'에 대해 좀 더 읽은 후에, 대신에 stdback-insertervector-for), 기본적으로 내 사용 사례를 설명합니다. 그러나, 나는 왜 cppreference가 그런 예를 포함 할 것인지 확신 할 수 없다. – Oleg

0

std::adjacent_difference 결과 반복기에 씁니다. 귀하의 경우 결과 iterator 가리키는 df, 0의 크기와 5의 용량을 가리 킵니다. 이러한 쓰기는 df, 의 예약 된 메모리에있을 것입니다하지만 컨테이너의 크기를 변경하지 않습니다, 그래서 크기는 여전히 것입니다 0이고, 예약 된 컨테이너 공간의 처음 3 정수는 귀하의 차이를 갖습니다. 결과를 보려면 쓰기 대상 컨테이너에 이미 쓰여지고있는 슬롯에 저장된 데이터가 있어야합니다.

그렇다면, adjacent_difference 의해 반환 반복기에 따라 적절한 크기 (행 컨테이너의 크기를 조정하면 차분 전에 원형 버퍼로 데이터를 입력해야하는 결과를보고한다.

+0

이 작업은 이중 작업처럼 들리며 'df'를 채우고 덮어 씁니다. 그들. 그게'boost :: circular_buffer'가하는 일인가 모르겠지만이 문제는 없었습니다. – Oleg