Определить модификатор ostream C++
Я генерирую сборку и хочу, чтобы весь сгенерированный код был выровнен. Это включает в себя что-то вроде cout<<"\t"<<left<<setfill(' ')<< setw(8);
перед каждой инструкцией. Как я могу объявить модификатор ostream, который спасет меня от написания всего этого кода в каждой строке. Я ищу что-то вроде:
ostream mod="\t"<<left<<setfill(' ')<< setw(8);
cout<<mod<<"addiu"<<"$sp, $sp, 24"<<endl;
Я знаю, что могу сделать это с помощью макроса, но я хочу знать, как я могу сделать это с объектом ostream.
2 ответа
Потоковая функция, которая принимает и возвращает std::ostream&
вызовет эту функцию в потоке. Вот как определяются некоторые стандартные манипуляторы, и это самый быстрый способ создать свой собственный, если им не нужно принимать никаких аргументов:
namespace cds {
std::ostream& pad(std::ostream& os) {
return os << '\t' << std::setfill(' ') << std::setw(8);
}
}
int main() {
std::cout << cds::pad << "Hello" << '\n'
<< cds::pad << "World" << '\n';
}
печатает:
$ ./SO
Hello
World
Как указано в комментариях, вам не нужно повторять setfill
, но, поскольку вы не знаете (с точки зрения автора манипулятора), что будет вызываться в промежуточном потоке, вы также можете.
Кроме того, как я объясняю здесь, многие разработчики, в том числе и я, рассматривают возможность использования endl
плохая практика.
ostream
определяет перегрузку operator<<
который принимает функцию потока, так что вы можете легко определить свои собственные манипуляторы:
#include <iostream>
#include <iomanip>
using namespace std;
ostream& foo(ostream& s) {
return s << hex << setw(4) << setfill('#');
}
int main() {
cout << foo << 42;
return 0;
}