Вы можете создать другую оболочку вокруг буфера stdout:
#include <iostream>
#include <iomanip>
int main() {
int x = 76;
std::ostream hexcout (std::cout.rdbuf());
hexcout << std::hex;
std::cout << x << "\n"; // still "76"
hexcout << x << "\n"; // "4c"
}
В функции:
void print(std::ostream& os) {
std::ostream copy (os.rdbuf());
copy << std::hex;
copy << 123;
}
Конечно, если производительность является проблемой, это немного дороже, потому что он копирует весь iosобъект (но не буфер), включая некоторые вещи, за которые вы платите, но вряд ли будете использовать, например, локаль.
В противном случае мне кажется, что если вы собираетесь использовать .flags(), лучше быть последовательным и использовать, .setf()а не <<синтаксис (чистый вопрос стиля).
void print(std::ostream& os) {
std::ios::fmtflags os_flags (os.flags());
os.setf(std::ios::hex);
os << 123;
os.flags(os_flags);
}
Как уже говорили другие, вы можете поместить вышеперечисленное (и .precision()и .fill(), но обычно не относящиеся к языку и словам вещи, которые обычно не будут изменены и тяжелее) в класс для удобства и для обеспечения безопасности исключений; конструктор должен принять std::ios&.