我已经成功使用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/

10-09 16:02