有一件困扰我一段时间的事情:
目前的智慧是,类型应该被保留在一个命名空间中,该命名空间只包含作为类型非成员接口一部分的函数(请参见《C++ 编码规范》Sutter 和 Alexandrescu,或此处),以防止 ADL 引入无关定义。
这是否意味着所有类都必须拥有自己的命名空间?如果我们假设一个类可能会在未来通过添加非成员函数来进行增强,那么将两个类型放入同一个命名空间就永远不安全了,因为其中任何一个都可能引入可能与另一个干扰的非成员函数。
我问这个问题的原因是,命名空间对我来说变得很麻烦。我正在编写一个头文件库,我发现自己正在使用诸如project::component::class_name::class_name之类的类名。它们的实现调用帮助函数,但由于这些函数不能在同一个命名空间中,它们也必须被完全限定!
编辑:
有几个答案建议 C++ 命名空间只是避免名称冲突的机制。这并不正确。在 C++ 中,采用参数的函数会使用参数依赖查找进行解析。这意味着当编译器尝试查找与函数名匹配的函数定义时,它将查看与其参数类型的命名空间中的每个函数来查找候选项。
这可能会带来意外的、不愉快的后果,详见A Modest Proposal: Fixing ADL。Sutter和Alexandrescu的规则是:除非函数属于该类的接口,否则永远不要将函数放在同一命名空间中。我不知道如何遵守这个规则,除非准备给每个类分配自己的命名空间。
欢迎提出更多建议!
using
声明或指令。 - Steve Jessopvoid foo(int)
和class bar;
放在同一命名空间中到底有什么问题?自变量查找(ADL)会导致什么问题? - jalfbar
传递给函数void baz(bar b)
时,baz
的实现会从bar
的命名空间中全部调用函数。如果baz
恰好调用了一个叫做foo
的东西,并且void foo(int)
比它要找的那个更匹配,那么它就会选择错误的foo
! - thehouse