tgoop.com/cxx95/39
Last Update:
#madskillz
Обертка над потоком вывода 🌊
У каждой крупной компании (и в FAANG) есть своя реализации std::string и/или разных строковых утилит.
Много где, прежде чем вывести немного видоизмененную строку в поток вывода (это объект с оператором <<, например std::cout, std::stringstream), создается новая строка:log << "Value is " << valueStr.Quote();Метод Quote() создаст новую строку с кавычками " по бокам. Такой код встречается тысячами, и вредит перфомансу ⏱, но это удобнее, чем выводить бесконечные "\"".
Попробуем сделать по аналогии с std::boolalpha "флаг" для "бесплатного" вывода строки. Мы хотим, чтобы можно было писать так:log << "Value is " << quote << valueStr;И это было бы аналогично записиlog << "Value is " << '"' << valueStr << '"';Как это можно сделать?
Пусть выражение ((объект потока) << quote) вернет объект TQuoteWrapper, а запись ((объект TQuoteWrapper) << str) вернет исходный поток с записанным туда str.
Для удобства будем работать со всеми типами потоков. Объект quote ничего не значит и нужен только для вышеуказанной записи.inline constexpr struct{} quote;Сам объект
template<typename TStream>
auto operator<<(TStream& stream, decltype(quote)) {
return TQuoteWrapper{stream};
}TQuoteWrapper имеет оператор <<, в котором записывает то, что нужно: template<typename TArg>По ссылке на godbolt можно посмотреть, что получилось 👍
TStream& operator<<(TArg&& arg) {
return Stream_ << '"' << std::forward<TArg>(arg) << '"';
}
Также можно сделать так, чтобы TQuoteWrapper эскейпил символы строки (например, заменял \" на \\\").
По ссылке на godbolt можно посмотреть, как я это сделал.
Другой подход к "бесплатному" выводу строки в нужном формате можно посмотреть в библиотеке abseil - Writing to Stream. В нем потоку отдается "легкий" объект:std::cout << absl::StreamFormat("\"%s\"", valueStr);Но есть и свои ограничения - нельзя по-полному перепахать строку (сделать escape символов) через printf-like аргумент
BY C++95
Share with your friend now:
tgoop.com/cxx95/39
