我已经成功使用cxx-prettyprint: A C++ Container Pretty-Printer记录了容器值。 (另请参阅Pretty-print C++ STL containers)即使在旧的VS-2005(VC8)编译器(带有prettyprint98.hpp header )上,它也可以像魅力一样工作,例如在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:
因此,这是cxx-pp中正式的UB,还是模板特化(在我看来,这似乎不像一个)。
关于iff UB的实际影响的评论将非常受欢迎。
最佳答案
在标准中,[namespace.std] / 1对此进行了覆盖(在问题中引用了它,但在这里也将其复制,因为它也是答案):
对于新的用户定义类型,operator<<
的重载没有任何“否则指定”。
因此,行为只是不确定的(无需诊断)。
从实用的 Angular 看,代码要么起作用要么就不起作用,但是与所有UB一样,我们应注意不要排除其他任何东西。
关于c++ - Cxx-prettyprint(用于标准容器)在 namespace std中定义其输出运算符-这是标准违规吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25120423/