2013-08-24 69 views
1

我在某處找到了這段代碼。它在屏幕上打印「abcd」,但以一種奇怪的方式。我希望有人告訴我它是如何工作:此打印代碼如何工作?

#include <iostream> 
#include <sstream> 

class X 
{ 
    typedef std::istreambuf_iterator<char> Iter; 
    Iter it; 
public: 
    X(std::streambuf* p) : it(p) { } 

    Iter begin() 
     { return it; } 
    Iter end() 
     { return Iter(); } 
}; 

void printbuf(X x, std::ostreambuf_iterator<char> it) 
{ 
    for (auto c : x) 
    { 
     *it = c; 
    } 
} 

int main() 
{ 
    std::stringbuf buf("abcd", std::ios_base::in | std::ios_base::out); 
    printbuf(&buf, std::cout); 
} 
+0

你能鏈接到哪裏找到它? – Borgleader

+0

@Borgleader對不起,它沒有鏈接到這麼 –

+0

這個你可能發現最令人困惑的部分是* both *參數傳遞給'printbuf()'的隱式構造。一個'X'由'stringbuf'地址隱式構造而成,'std :: ostreambuf_iterator <>'同樣由'std :: cout'隱式構造。克服這一點,理解變得更加簡單。 – WhozCraig

回答

4

我們有一個類X其中封裝了一個它們寫入std::coutistreambuf_iterator <char>。這是一種迭代器類型,它允許我們將流緩衝區視爲標準算法的迭代器範圍。

class X 
{ 
    typedef std::istreambuf_iterator<char> Iter; 
    Iter it; 
public: 

該類可以從指向流緩衝區實例的指針構造。

X(std::streambuf* p) : it(p) { } 

它暴露begin()end()成員函數,以允許它與基於範圍的for循環使用。

Iter begin() 
     { return it; } 
    Iter end() 
     { return Iter(); } 
}; 

printbuf()是接受我們的範圍類X的實例的功能,以及一個ostreambuf_iterator <char>,-你哪個猜對了,允許我們使用的輸出流緩衝區作爲輸出迭代

void printbuf(X x, std::ostreambuf_iterator<char> it) 
{ 

所以我們遍歷輸入範圍中的每個字符。

for (auto c : x) 
    { 

如果您還沒有與輸出迭代處理之前,你可以把它們作爲一個對象類似於一個指針,以你編寫使用提領和分配值。 back_insert_iterator是一個常用的輸出迭代器,用於構建容器 - 通常使用back_inserter構建它。但我離題了。

我們將每個字符複製到輸出迭代器。

 *it = c; 
    } 
} 

int main() 
{ 

這裏我們構造一個字符串緩衝區,它既是輸入流輸出緩衝區,也是輸出流緩衝區。在這個例子中我們只使用輸入能力。

std::stringbuf buf("abcd", std::ios_base::in | std::ios_base::out); 

現在我們使用隱式構造X實例來對待字符串緩衝區作爲一個迭代器範圍。然後,我們將該範圍複製到輸出流緩衝迭代器(也隱式構造)到std::cout

printbuf(&buf, std::cout); 
} 

效果是我們循環緩衝區中的每個字符並將其複製到標準輸出。

2
printbuf(&buf, std::cout); 

傳遞std::stringbuf*作爲第一個放慢參數引起的X隱式建築相匹配printbuf()

,也爲第二個參數,一個隱含的 造成std::ostreambuf_iterator<char>的實例是從std::cout(std :: ostream)

void printbuf(X x, std::ostreambuf_iterator<char> it) 
{ 
    for (auto c : x) 
    { 
     *it = c; 
    } 
} 

在printbuf,foreach循環(基於for循環範圍)使用X::begin()X::end()循環遍歷所有字符包裹std::stringbuf並經由std::ostreambuf_iteratorit