C++中的根命名空间编码规范

10
你会推荐在全局命名空间前加上::吗?(例如::std::cout而不是std::cout)为什么?这样做对C++编译器的解析速度更快吗?
谢谢。
5个回答

11

仅通过这种方式进行消歧。

我有一段代码,由于我在命名空间X中具有用于标准偏差的函数- std,因此这是必要的。每当我想要访问std命名空间时,我需要使用::std,否则编译器将认为我正在引用该函数。

具体示例:

namespace X {
    double std(::std::vector<double> const& values) { … }

    void foo(::std::vector<double> const& values) {
        ::std::cout << std(values) << ::std::endl;
    }
}

重命名函数不是更简单吗,真的 :P? - Matthieu M.
4
@MatthieuM 这不是正确的解决方案。给函数命名已经够难了。这个函数的名称是正确的(“std”是“标准差”最常见的缩写),不应该仅仅为了避免名称冲突而改变它。 - Konrad Rudolph
5
举一个在另一个命名空间中确实需要使用名称"std"的示例,给出+1。 - Bo Persson

5
这与解析速度无关。C++使用参数依赖名称查找-Koenig Lookup,当你必须确保编译器使用全局根命名空间中的符号时,需要在前面加上::。如果不这样做,编译器可能会在适当时候(取决于查找方法)从其他命名空间中使用函数定义。
因此,最好不要这样做,除非必须这样做。

1
ADL指的是在查找未经限定的函数调用时,参数的命名空间将被添加到候选集中,这与任何限定符标识符无关,这也是问题所在:限定调用与完全限定(包括根命名空间)调用。 - David Rodríguez - dribeas
ADL适用于所有非限定函数调用的名称查找。@trenki正确指出使用::会显著改变名称查找。通常不是想要的结果。 - James Kanze

2

你不需要这样做,因为编译器会

a) 找到它 b) 如果有任何歧义,如输出错误

namespace foo
{
  int test()
  {
    return 42;
  }
}

namespace bar
{
  namespace foo
  {
    int test()
    {
      return 42;
    }
  }
}

int main()
{
  using namespace bar;
  return foo::test(); // error, could be ::foo::test or ::bar::foo::test
}

0

我看不出有任何好的理由这样做。它会使代码变得难以阅读,只有在你必须明确告诉编译器使用根命名空间时才应该使用它。比如当存在歧义时。


-1

不要这样做。这会使你的代码混乱,并禁用实现自己版本的函数选项。


问题是是否推荐它,但我不会,因为我在第二句话中列出的原因。;) - filmor
在这种情况下,你错了:它并不会。使用显式命名空间(无论是否由全局命名空间限定符“::”前缀)将始终使自制函数的变体无法使用(除非您正在专门化std::swap)。命名空间是否由“::”前缀无关紧要。 - Konrad Rudolph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接