Я успешно использую cxx-prettyprint: C ++ Container Pretty-Printer < / em> для записи значений контейнера. (См. Также Контейнеры STL C ++ с красивой печатью). Он прекрасно работает даже на старый компилятор VS-2005 (VC8) (с заголовком prettyprint98.hpp) также хорошо работает на VS2017-2019 при его использовании, например чтобы значения контейнера можно было распечатать в модульных тестах.
Изучая его совместимость с Boost.Format, я с удивлением обнаружил, что он просто работает из коробки, когда другие вопросы говорят о том, что этого не должно быть, потому что ADL не должен работать с оператором вывода, предоставленным пользователем.
Заглянув в заголовок cxx-pp, я обнаружил, что это просто работает, потому что библиотека определяет свои операторы вывода внутри пространства имен std
:
// Main magic entry point: An overload snuck into namespace std.
// Can we do better?
namespace std
{
// Prints a container to the stream using default delimiters
template<typename T, typename TChar, typename TCharTraits>
inline typename enable_if< ::pretty_print::is_container<T>::value,
basic_ostream<TChar, TCharTraits> &>::type
operator<<(basic_ostream<TChar, TCharTraits> & stream, const T & container)
{
return stream << ::pretty_print::print_container_helper<T, TChar, TCharTraits>(container);
}
}
....
Очевидно, авторы не были уверены в этом на 100%: qq "Можем ли мы сделать лучше?"
Добавление чего-либо в пространство имен std
- это формально UB:
[C++11: 17.6.4.2.1/1]:
Поведение программы C ++ не определено, если она добавляет объявления или определения в пространство именstd
или в пространство имен в пространстве именstd
, если не указано иное. Программа может добавить специализацию шаблона для любого шаблона стандартной библиотеки в пространство имен std только в том случае, если объявление зависит от определяемого пользователем типа, а специализация соответствует требованиям стандартной библиотеки для исходного шаблона и не запрещена явно.
Итак, это в cxx-pp формально UB, или это специализация шаблона (мне это не кажется).
Комментарии относительно практического воздействия этого, если только UB, будут очень приветствоваться.
std
, вероятно, было не самой хорошей идеей. (Просто это так здорово сработало ...) Приветствуются исправления и запросы на вытягивание. (И да, подтолкните меня, если я не отвечу вовремя.) - person Kerrek SB   schedule 04.08.2014std
, поскольку у нас могут быть аргументы, которые только вstd
, напримерstd::cout
иstd::vector<int>
. - person Kerrek SB   schedule 12.08.2014cout << pretty_print(arg) << ...
... что, IMHO, вариант, и не такой уж плохой. Конечно, это часто выходит из строя в общем случае, и для меня перегрузкаstd
, хотя и не соответствует требованиям, является лучшим вариантом, чем если бы она не работала в некоторых случаях. - person Martin Ba   schedule 12.08.2014