這實際上是我第一次真正使用過濾器 streambuf的。鑑於這樣的:
std::ostream& operator<<(std::ostream& dest,
std::vector<Matrix> const& object);
class MyClass
{
std::vector<Matrix> m;
};
std::ostream& operator<<(std::ostream& dest, MyClass const& object)
{
// ...
{
// Scope to control lifetime of the IndentingStreambuf...
// Could be (probably should be) in a separate function.
IndentingStreambuf indent(dest)
dest << m;
}
// ...
}
其中:
class IndentingStreambuf : public std::streambuf
{
std::streambuf* myDest;
std::ostream* myOwner;
bool myIsAtStartOfLine;
protected:
int overflow(int ch)
{
if (myIsAtStartOfLine && ch != EOF && ch != '\n') {
myDest->sputn(" ", 4);
}
myIsAtStartOfLine = ch == '\n';
return myDest->sputc(ch);
}
public:
IndentingStreambuf(std::streambuf* dest)
: myDest(dest)
, myOwner(NULL)
, myIsAtStartOfLine(true)
{
}
IndentingStreambuf(std::ostream& dest)
: myDest(dest.rdbuf())
, myOwner(&dest)
, myIsAtStartOfLine(true)
{
myOwner->rdbuf(this);
}
~IndentingStreambuf()
{
if (myOwner != NULL) {
myOwner->rdbuf(myDest);
}
}
};
編輯:
我剛剛看了你想要的輸出更詳細一點。該 相同的基本IndentingStreambuf
作品,但
你必須去適應它支持任意縮進(如 參數構造函數),
初始化myIsAtStartOfLine
到false
,並且
在輸出A(i) = [
後調用它。
當然而且,定義爲operator<<
適當Matrix
。
或者,你可以只使用std::ios_base::xalloc
來 獲得一個地方,你可以告訴operator<<
爲 Matrix
有關縮進。沿線的東西:
static long& getMatrixIndent(std::ostream& dest)
{
static int ourIndex = std::ostream::xalloc();
return dest.iword(ourIndex);
}
class indent
{
int myIndent;
public:
indent(int n) : myIndent(n) {}
friend std::ostream& operator<<(std::ostream& dest,
indent const& manip)
{
getMatrixIndent(dest) = myIndent;
}
};
std::ostream& operator<<(std::ostream& dest, Matrix const& object)
{
int indent = getMatrixIndent(dest);
// ...
}
這比過濾streambuf的靈活性要小得多。 特別是,它不能用於您的 不控制operator<<
的實現的類型。但它簡單,並且有時也很有用。
(我要說,其實,使用C++的人應該熟悉 有兩種技術,但我不知道任何教程文本 其中甚至提到他們。而在這個世界上,有大量 的C++用戶仍然在寫while (! file.eof())
,它的 可能太多要求。)
我認爲你必須創建自己的流包裝類,將輸入流包裝在你的'operator >>'中並使用包裝器來輸出矩陣。 – Angew 2013-02-14 14:54:13