Ddor
Ddor

Reputation: 347

Chaining C++ stream manipulators into single variable

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;

Upvotes: 2

Views: 219

Answers (2)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122460

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).

Upvotes: 3

Quentin
Quentin

Reputation: 63124

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

Upvotes: 4

Related Questions