C++中缺少命名空间限定符没有错误

no error on lack of namespace qualifiers in C++

本文关键字:有错误 命名空间 C++      更新时间:2023-10-16

我正在做一个小C++项目,遇到了一些关于命名空间的行为,这对我来说看起来真的很奇怪。我已经在命名空间中定义了我所有的类和函数my_project

// point.hpp:
namespace my_project {
    template <size_t dim> class Point { /* snip */ };
}
// convex_hull.hpp:
namespace my_project {
    std::vector<size_t> convex_hull(const std::vector<Point<2> >& xs);
}

然后我去为所有内容编写一个测试:

// convex_hull_test.cpp:
#include <my_project/convex_hull.hpp>
using my_project::Point;
int main()
{
  Point<2> p1 = /* snip */;
  std::vector<Point<2> > xs = {p1, p2, p3, p4, p5, p6};
  std::vector<size_t> hull = convex_hull(xs);
  /* snip */
  return 0;
}

一切都很好,但第二天我又看了一遍,意识到我应该写下这一行:

  std::vector<size_t> hull = my_project::convex_hull(xs);

因为我从来没有using my_project::convex_hull过任何地方。然而,当我编译它时,我没有因为使用未定义的符号而收到任何错误。为什么我可以在没有命名空间前缀的情况下使用此函数

对于我定义的其他几个函数也是如此。当我离开行using my_project::Point;时,我确实会在没有命名空间限定的情况下使用Point而出错。关于命名空间限定的函数、类或模板是否有不同的规则?规则是否相同,表明还有其他奇怪的事情发生?

我在多台机器上用 clang、g++ 和 icc 尝试过这个。我试图构造一个最小的测试用例,但编译器抛出了我认为在这种情况下应该出现的错误。

xs的类型必须在命名空间my_project中可用。正在发生的事情称为依赖于参数的查找。

C++标准允许这样做。如果要预防 ADL,请尝试

std::vector<size_t> hull = (convex_hull)(xs);

放置括号可以防止依赖于参数的查找,请尝试一下,编译器应该抱怨。

编辑

基于OP的编辑

参见艾伦·斯托克斯(Alan Stokes)对此答案的评论。