2010-02-03 2 views
0

참고 : 답변을 바탕으로 편집하여보다 적절한 답변을받을 수 있습니다.반복 가능한 시퀀스를 스트림으로 처리하기 위해 std :: basic_streambuf를 확장하는 방법은 무엇입니까?

나는 지난 몇 년 동안 만든 Joop이라는 C++ 템플릿 모음을 가지고 있습니다. 이 라이브러리는 주로 "범용"범주에 속하지 않지만 다른 프로젝트에 계속 적용 할 수있는 라이브러리로 구성되어 있습니다. 따라서 대부분 Boost와 같은 다른 라이브러리에 해당 라이브러리가 없습니다.

이러한 클래스 중 하나는 seqstream입니다. 이것은 반복 가능한 모든 시퀀스를 "문자 유형"이 시퀀스의 값 유형 인 일반 STL 류 스트림으로 취급 할 수있게한다는 아이디어입니다.

이 클래스의 이론적 근거는 두 가지입니다. 첫째, 잠재적으로 비선형이고 인접하지 않은 시퀀스를 선형적이고 연속적으로 보이게 만드는 인터페이스를 제공해야합니다. 두 번째로 스트림의 모든 객체를 마치 하나의 복잡하고 큰 문자처럼 취급해야합니다. 스트림을 시퀀스로 처리하는 표준 방법이 있습니다. 왜 다른 방법으로 스트림을 처리할까요?

현재 seqstream은 첫 번째 요소, 마지막 요소 및 현재 요소에 대해 세 개의 반복자를 래핑합니다. seqstreambasic_seqbuf으로 바꾸고 싶습니다. 표준 스트림에 연결할 수 있습니다. 아무도 이런 종류의 동작을 제공하기 위해 std::basic_streambuf을 확장하기 시작한 리소스를 제공 할 수 있습니까? 기록 가능한 seqbuf 허용 여부

또한, 상기 seqbuf에 객체를 기록하는 등 하지 직렬화를 목적을 수행하지만, insert() 방법에 적절한 호출을하거나 사용자 지정 삽입 반복기를 사용하는 것이 매우 인 std::back_insert_iterator.

편집 : 여기

seqstream 현재 사용하는 방법의 예입니다

// Create a sequence of objects. 
std::vector<std::string> sequence; 
for (int i = 0; i < 10; ++i) { 
    std::ostringstream stream; 
    stream << "Element " << i << "."; 
    sequence.push_back(stream.str()); 
} 

// Create a seqstream wrapping that sequence. 
joop::seqstream< std::vector<std::string> > seqstream(sequence.begin(), sequence.end()); 

// Read the sequence like a stream. 
std::string element; 
while (seqstream >> element) // OR seqstream.get(element) 
    std::cout << element << '\n'; 
+0

대신 basic_streambuf에서 상속하지 않은 이유가 있습니까? – MSN

+0

그것은 그것이가는 길일 수도있는 것처럼 보입니다. 그런 다음 객체 (예 :'seqstreambuf')를 표준 스트림에 연결할 수 있습니다. –

+0

표준형 라이브러리는 스트림처럼 컨테이너를 처리하기위한 래퍼를 작성할 때까지 제한자와 같은 스트림을 처리하는 래퍼를 제공하는 경향이 있습니다. 아니면 혼란스러워. seqstream의 예제 사용법을 알려 줄 수 있습니까? –

답변

1

sstream의 예를 살펴 혼동 될 수 있지만, 당신은 아마 싶지 않아 새로운 스트림 클래스. basic_stringstream 소스에서 예를 들어 지금 찾고, 그 클래스의 유일한 목적은

  • str 기능을 제공

    에 자사의 메소드를 호출 할 때
  • 기본 버퍼의 VTABLE을 피하기 (그냥 기본 버퍼의 str 호출)
  • 스트림 CLA
  • 변화 rdbuf의 반환 basic_stringbuf* 가치 (그러나 str 대한 접근을 제공하고 있기 때문 불필요)

sses는 거의 없으며 실제로는 basic_streambuf 유형의 기본 버퍼를 호출하는 것 외에는 어떤 기능도 갖기로되어 있지 않습니다. 예를 들어,이 작업을 수행 할 수 있습니다

string str("Hello, world!"); 
stringbuf buf(str); // subclass of basic_streambuf 
iostream pseudo_stringstream(&buf); 
    // pseudo_stringstream can do anything a stringstream can do. 
    // (not necessarily with the same syntax) 

또한, 모든 스트림은 하나 basic_istream, basic_ostream, 또는 둘 모두에서 상속로되어있다. 스트림이 올바르게 상속되지 않으면 인서 터/추출기 기능이 작동하지 않을 수 있습니다.이 삽입 선언은 완벽하게 잘 있습니다 : 당신이 iostream 행동을 원하는 경우

operator<<(ostream os, MyData d); // not a template at all 
     // templated, but requires correct inheritance: 
template< class C > operator<<(basic_ostream<C> os, MyData d); 

따라서, 당신은 basic_streambuf의 서브 클래스를 구현하고 그것이 basic_iostream에 연결해야합니다.


그러나 실제 목표는 무엇입니까? 일반적인 이터레이터에 비해 메모리 기반 스트림의 장점은 무엇이며 back_insert_iterator 일 수 있습니까? 반복과 동일한 코드를 직렬화에 사용 하시겠습니까? 시퀀스를 마치 스트림처럼 보이게하지 않으려면 stream_iterator을 사용하여 스트림을 시퀀스처럼 보이게하고 싶을 것입니다.

+0

두 가지 목표가 있습니다. 우선, 잠재적으로 비선형이고 인접하지 않은 시퀀스를 선형적이고 연속적으로 보이게 만드는 인터페이스를 제시하십시오. 두 번째로 스트림의 모든 객체를 단일 문자 인 것처럼 취급합니다. 스트림 이디엄은 완벽한 일치입니다. 'seqstream'은'streambuf'를 시퀸스로 대체하고 요소를 문자로 취급합니다. 'basic_streambuf'의 서브 클래스를 만들 수 있는지 알아 보겠습니다. 이를 별도로 요구 사항을 충족하는 클래스로 분할해야 할 수도 있습니다. –

+0

@ 존 : 정의에 의한 시퀀스는 이미 "선형으로 보인다". Contiguity는 포인터 연산을 할 수 있다는 것을 의미하며 컨테이너가'vector' 인 경우에만 작동합니다. 스트림은 그 하나의 비트에 도움이되지 않습니다. "단일 문자로 취급"한다는 것은 무슨 뜻입니까? 스트림의 요점은 버퍼링 된 I/O를 제공하는 것이며, 그렇게하지 않는 것 같습니다. – Potatoswatter

+0

@Potatoswatter : 선형으로 부여됩니다. 연속성은 잘못된 용어이기도하지만 사용할 수있는 유일한 용어입니다. 스트림은 시퀀스만큼이나 연속적입니다. 반복자는 포인터가 아니기 때문에 매우 간단합니다. "하나의 인물로 취급하라"는 의미는 객체를 깨뜨리지 않고 그것을 직렬화하지 않는다는 것을 의미합니다. 실제로 두 가지 일반화로 버퍼링 된 I/O를 수행하고 있습니다. 문자는 모든 객체가 될 수 있으며 버퍼는 모든 시퀀스가 ​​될 수 있습니다. –

관련 문제