| io/own-manipulator.cc - Programming our own manipulator - with two parameters. | Lecture 3 - slide 21 : 27 Program 3 |
// Programming a stream manipulator with two functions:
#include <iostream>
#include <string>
using namespace std;
// A struct that encapsulates the manipulator constituents: an appropriate function pointer, a counter, and a string:
struct stream_manipulator {
basic_ostream<char>& (*f)(basic_ostream<char>&, int, string); // a function pointer
int counter;
string str;
// A stream_manipulator constructor:
stream_manipulator(basic_ostream<char>&(*ff)(basic_ostream<char>&, int, string),
int i,
string ss): f{ff}, counter{i}, str{ss} {
}
};
// Overloading operator<< on basic_ostream<C,Tr> os and stream_manipulator m.
// Call m.f on the stream os, the counter in m, and the string in m:
template<typename C, typename Tr>
basic_ostream<C,Tr>& operator<<(basic_ostream<C,Tr>& os, const stream_manipulator& m){
m.f(os, m.counter, m.str); // call the lambda expression located in kn_endl.
return os; // for chaining purposes.
}
inline stream_manipulator kn_endl(int n, string suffix){
auto h = [](basic_ostream<char>& s, int n, string str) -> basic_ostream<char>& {
for(int i = 0; i < n; i++) s << str << endl;
return s;
};
return stream_manipulator(h, n, suffix);
}
int main(){
int a_number{5};
cout << "A test:" << kn_endl(a_number, "KN")
<< a_number << kn_endl(3, "OK") << "The end" << endl;
}