我已成功使用cxx-prettyprint: A C++ Container Pretty-Printer记录容器值。 (另请参阅Pretty-print C++ STL containers)即使在旧的VS-2005(VC8)编译器(带有prettyprint98.hpp标头)上,它也可以像魅力一样工作,例如,在VS2017-2019上使用时也能很好地工作。使容器值在单元测试中可打印。
[在研究其与Boost.Format的互操作性时,令我感到惊讶的是,当other questions suggest it shouldn't时,它就开箱即用,因为对于用户提供的输出运算符,ADL应该会失败。
查看cxx-pp header,我发现它只是可以工作,因为库确实做了定义其输出运算符内部 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
命名空间添加内容是formally UB:
[C++11: 17.6.4.2.1/1]:
除非另有说明,否则C ++程序的行为如果将声明或定义添加到名称空间std
或名称空间std
中的名称空间,则不确定。仅当声明依赖于用户定义的类型并且该特殊化满足原始模板的标准库要求且未被明确禁止时,程序才可以将任何标准库模板的模板特殊化添加到命名空间std。所以,这在cxx-pp中是正式的UB,还是它的模板专门化(对我来说似乎不像是一个。)>
非常欢迎您对iff UB关于此问题的实际影响发表评论。
我已成功使用cxx-prettyprint:一个C ++容器Pretty-Printer来记录容器值。 (另请参见Pretty-print C ++ STL容器)即使在旧版VS-2005上,它也可以像魅力一样工作(...
这在标准中由[namespace.std] / 1覆盖(在问题中引用了该问题,但在此也将其复制,因为它也是答案):
除非另有说明,否则如果C ++程序的行为向名称空间
std
或名称空间std
中的名称空间添加声明或定义,则其行为是不确定的。