2010-02-03 29 views
0

注意:根據回覆進行編輯以獲得更合適的答案。如何擴展std :: basic_streambuf以將任何可迭代序列視爲流?

我有多年來所做的C++模板集合,我稱之爲Joop。它主要包括不完全屬於「通用」範疇的庫,但它們足夠有用,因此我一直將它們放在不同的項目中,所以大多數庫在其他庫(例如Boost)中沒有等價物。

其中一個類是seqstream。這個想法是,它允許你將任何可迭代的序列視爲普通的STL類流,其「字符​​類型」是序列的值類型。

這個班的理由是雙重的。首先,它應該提供一個界面,使任何潛在的非線性,不連續的序列看起來線性和連續;其次,它應該將流中的任何對象看作是一個單一的,複雜的大型角色。有一種將流視爲序列的標準方法,那麼爲什麼不用另一種方式呢?

目前,seqstream爲第一個,最後一個和當前元素包裝了三個迭代器。我想用可插入標準流的basic_seqbuf替換seqstream。任何人都可以提供資源讓我開始延長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 2010-02-03 22:21:53

+0

這看起來可能是要走的路。然後,我可以將該對象(比如'seqstreambuf')插入標準流中。 – 2010-02-04 02:41:26

+0

所以,如果你寫了一個包裝器來處理一個像流的容器,那麼標準的圖書館往往會提供像constainer一樣處理流的包裝器。或者我混淆了。你能舉一個seqstream的例子嗎? – 2010-02-04 04:07:52

回答

1

它可以是混亂看在sstream的例子,但是你可能不希望一個新的流類。在basic_stringstream源現在正在尋找一個例子,這個類的唯一目的就是

  • 提供str功能(它只是調用底層緩衝區的str
  • 避免潛在的緩衝區的虛函數表調用其方法時
  • 變化rdbuf的返回值來basic_stringbuf*(但是這是不必要的,因爲被設置用於str的存取器)

流CLA 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_istreambasic_ostream,或兩者繼承。如果您的流沒有正確繼承,插入器/提取器功能可能不起作用。這些插件聲明是完美的罰款:

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); 

因此,如果你想iostream的行爲,你需要實現的basic_streambuf一個子類,並將其連接到一個basic_iostream


但是,您的實際目標是什麼?支持內存的流優於通常的迭代器,也許有些back_insert_iterator?你想使用相同的代碼序列化迭代?您可能想使流看起來像使用stream_iterator的序列,而不是使序列看起來像流。

+0

有兩個目標。首先,提出一個界面,使任何潛在的非線性,不連續的序列看起來線性和連續;其次,將流中的任何對象視爲單個字符。流成語是完美的搭配。 'seqstream'用一個序列替換'streambuf',並將元素視爲字符。我將研究是否使'basic_streambuf'的子類可以工作。我可能需要將它分成分別滿足要求的類。 – 2010-02-04 02:35:01

+0

@Jon:按照定義,序列已經「看起來線性」。鄰接意味着能夠進行指針運算,並且只有在容器是「矢量」流時才起作用,並不能幫助這一點。 「把......當作單個字符」是什麼意思?流的要點是提供緩衝I/O,而你似乎根本就沒有這樣做。 – Potatoswatter 2010-02-04 04:21:34

+0

@Patatoswatter:授予線性。連續性也是一個錯誤的術語,但也是唯一可用的術語:流與序列允許的連續性相似,很簡單,因爲迭代器不是指針。 「作爲單個字符對待」意味着不要破壞對象,也不要將其串行化。我的確在做緩衝I/O,只有兩個概括:字符可以是任何對象,並且緩衝區可以是任何序列。 – 2010-02-04 04:36:47