Cxx-prettyprint(用于标准容器)在名称空间std内定义了其输出运算符-这是一种标准违规吗? [英] Cxx-prettyprint (for standard containers) defines its output operators inside namespace std - is this a standard violation?
问题描述
我已经成功使用 cxx-prettyprint:C ++容器Pretty-Printer 记录容器值. (另请参见 Pretty-print C ++ STL容器)即使在旧的VS-2005(VC8)编译器(带有prettyprint98.hpp标头),在使用VS2017-2019时也可以很好地工作,例如使容器值在单元测试中可打印.
I have been successfully using cxx-prettyprint: A C++ Container Pretty-Printer to log container values. (See also Pretty-print C++ STL containers) It's working like a charm even on the old VS-2005 (VC8) compiler (with the prettyprint98.hpp header), also works well on VS2017-2019 when using it e.g. to make container values printable in Unit Tests.
在研究其与Boost.Format的互操作性时,令我惊讶的是,当
While studying its interoperability with Boost.Format, I found to my surprise that it simply works out of the box, when other questions suggest it shouldn't because ADL should fail for a user provided output operator.
查看 cxx-pp标头之所以能够正常工作,是因为该库确实在std
名称空间内
Looking into the cxx-pp header I found that it simply works because the library does define its output operator(s) inside the std
namespace:
// 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"我们可以做得更好吗?"
Obviously the authors were not 100% confident with this: qq "Can we do better?"
向std
命名空间添加内容是正式为UB :
Adding something to the std
namespace is formally UB:
[C++11: 17.6.4.2.1/1]:
如果C ++程序的声明或定义添加到名称空间std
或名称空间std
中的名称空间,则行为不确定.仅当声明依赖于用户定义的类型并且该专业化满足原始模板的标准库要求且未被明确禁止时,程序才可以将任何标准库模板的模板专业化添加到命名空间std.
[C++11: 17.6.4.2.1/1]:
The behavior of a C++ program is undefined if it adds declarations or definitions to namespacestd
or to a namespace within namespacestd
unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
那么,这在cxx-pp中是正式的UB,还是模板专门化(对我而言似乎不是一个).
So, is this in cxx-pp formally UB, or is it a template specialization (It doesn't seem like one to me).
非常欢迎对iff UB对此功能的实际影响发表评论.
Comments as to the practical impact of this, iff UB, would be very welcome.
推荐答案
在标准中,[namespace.std]/1对此进行了覆盖(在问题中引用了它,但在这里也将其复制出来,因为它也是答案):
This is covered by [namespace.std]/1 in the standard (which is quoted in the question but reproducing it here as it is also the answer):
如果C ++程序的声明或定义添加到名称空间
std
或名称空间std
中的名称空间中,则除非定义,否则其行为是不确定的.
The behavior of a C++ program is undefined if it adds declarations or definitions to namespace
std
or to a namespace within namespacestd
unless otherwise specified.
对于新的用户定义类型,operator<<
的重载没有任何否则指定".
There isn't any "otherwise specified" for overloads of operator<<
for new user-defined types.
因此行为只是不确定的(不需要诊断).
So the behaviour is just undefined (with no diagnostic required).
从实用的角度看,代码似乎是行得通的还是行不通的,但是与所有UB一样,我们应注意不要将其他任何内容排除在外.
In practical terms it seems like that either the code will work or it won't, but as with all UB we should be careful not to rule anything else out.
这篇关于Cxx-prettyprint(用于标准容器)在名称空间std内定义了其输出运算符-这是一种标准违规吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!