Я успешно использовал cxx-prettyprint: С++ Container Pretty-Printer для регистрации значений контейнера. (См. Также Pretty-print С++ STL-контейнеры) Он работает как прелесть нашего компилятора VS-2005 (VC8). (с заголовком prettyprint98.hpp)
Изучая его совместимость с Boost.Format, я с удивлением обнаружил, что он просто работает из коробки, когда другие вопросы говорят, что это не должно, поскольку ADL должен выйти из строя для пользователя, предоставленного оператором вывода.
Заглядывая в cxx-pp header, я обнаружил, что он просто работает, потому что библиотека определяет свой оператор вывода (ов) внутри пространства имен std
:
namespace std
{
// Prints a print_container_helper to the specified stream.
template<typename T, typename TChar, typename TCharTraits, typename TDelimiters>
inline basic_ostream<TChar, TCharTraits> & operator<<(basic_ostream<TChar, TCharTraits> & stream,
const ::pretty_print::print_container_helper<T, TChar, TCharTraits, TDelimiters> & helper)
{
helper(stream);
return stream;
}
....
Добавление чего-то в пространство имен std
формально UB:
[C++11: 17.6.4.2.1/1]:
Поведение программы на С++ undefined, если оно добавляет объявления или определения в пространство именstd
или в пространство имен в пространстве именstd
, если не указано иное. Программа может добавить специализацию шаблона для любого стандартного шаблона библиотеки в пространство имен std только в том случае, если объявление зависит от пользовательского типа, а специализация соответствует стандартным требованиям библиотеки для исходного шаблона и явно не запрещена.
Итак, это в cxx-pp формально UB, или это шаблонная специализация (для меня это не похоже).
Комментарии относительно практического воздействия этого, если UB, были бы очень желанными.