Chaining C++ stream manipulators into single variable

210 Views Asked by At

I am chaining some stream manipulators in an ofstream like so:

std::string filename = "output.txt";
std::ofstream outputFile;
outputFile.open(filename, std::ios::trunc);
outputFile << std::setw(5) << std::scientific << std::left << variable;

Is it possible to do something like this instead?:

std::string filename = "output.txt";
std::ofstream outputFile;
outputFile.open(filename, std::ios::trunc);
std::ostream m;
m << std::setw(5) << std::scientific << std::left;   // Combine manipulators into a single variable
outputFile << m << variable;
2

There are 2 best solutions below

2
Quentin On BEST ANSWER

A stream manipulator is just a function that a stream calls on itself through one of the operator << overloads (10-12 in the link). You just have to declare such a function (or something convertible to a suitable function pointer):

constexpr auto m = [](std::ostream &s) -> std::ostream& {
    return s << std::setw(5) << std::scientific << std::left;
};
std::cout << m << 12.3 << '\n';

See it live on Wandbox

0
463035818_is_not_an_ai On

You can write your own manipulator:

struct my_manipulator{};

std::ostream& operator<<(std::ostream& o, const my_manipulator& mm) {
     o << std::setw(5) << std::scientific << std::left;
     return o;
};

This would allow you to write

outputFile << my_manipulator{} << variable;

PS: Io-manipulators modify the state of the stream. Hence it cannot work exactly the way you asked for. You are modifying the state of m. Transferring the state from one stream to another is possible, but imho more complicated than necessary.

PPS: Note that my way of defining a custom io-manipulator is ok-ish, but to see an implementation that is more in the spirit of stream manipulators see this answer (usually io-manipulators are functions, I used a tag which requires a tiny bit more boilerplate).