Объединение потоковых манипуляторов C ++ в одну переменную - PullRequest
2 голосов
/ 06 марта 2020

Я подключаю некоторые потоковые манипуляторы в офстриме, например так:

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

Возможно ли сделать что-то подобное вместо этого?:

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 ]

4 голосов
/ 06 марта 2020

Манипулятор потока - это просто функция, которую поток вызывает для себя через одну из перегрузок operator << (10-12 в ссылке). Вам просто нужно объявить такую ​​функцию (или что-то, что можно преобразовать в подходящий указатель на функцию):

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

Смотрите ее в прямом эфире на Wandbox

3 голосов
/ 06 марта 2020

Вы можете написать свой собственный манипулятор:

struct my_manipulator{};

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

Это позволит вам написать

outputFile << my_manipulator{} << variable;

PS: Io-манипуляторы изменяют состояние потока. Следовательно, он не может работать именно так, как вы просили. Вы изменяете состояние m. Передача состояния из одного потока в другой возможна, но imho сложнее, чем необходимо.

PPS: обратите внимание, что мой способ определения пользовательского io-манипулятора - это нормально-i sh, но посмотреть на реализацию это больше в духе потоковых манипуляторов, см. этот ответ (обычно io-манипуляторы являются функциями, я использовал тег, который требует чуть больше шаблонного).

...