包装cout等ostream对象的方法

http://stackoverflow.com/questions/1134388/stdendl-is-of-unknown-type-when-overloading-operator

技术关键在于std::endl是一个函数  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>

struct MyStream
{
template <typename T>
MyStream& operator<<(const T& x)
{
std::cout << x;

return *this;
}


// function that takes a custom stream, and returns it
typedef MyStream& (*MyStreamManipulator)(MyStream&);

// take in a function with the custom signature
MyStream& operator<<(MyStreamManipulator manip)
{
// call the function, and return it's value
return manip(*this);
}

// define the custom endl for this stream.
// note how it matches the `MyStreamManipulator`
// function signature
static MyStream& endl(MyStream& stream)
{
// print a new line
std::cout << std::endl;

// do other stuff with the stream
// std::cout, for example, will flush the stream
stream << "Called MyStream::endl!" << std::endl;

return stream;
}

// this is the type of std::cout
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;

// this is the function signature of std::endl
typedef CoutType& (*StandardEndLine)(CoutType&);

// define an operator<< to take in std::endl
MyStream& operator<<(StandardEndLine manip)
{
// call the function, but we cannot return it's value
manip(std::cout);

return *this;
}
};

int main(void)
{
MyStream stream;

stream << 10 << " faces.";
stream << MyStream::endl;
stream << std::endl;

return 0;
}