2016-02-28 63 views
2

我工作的一个小C++项目的任何错误,冲进关于命名空间看起来很奇怪我的一些行为。我定义了我所有的类和函数命名空间my_project上缺乏C++空间限定符

// 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没有命名空间的资格。有关命名空间限定的函数,类或模板有不同的规则吗?规则是否一样,表明还有其他奇怪的事情发生?

我试图与铛,g ++以及ICC,多于一台机器上。我试图构造一个最小的测试用例,但编译器抛出了我认为应该在这种情况下出现的错误。

回答

4

xs的类型必须在命名空间my_project中可用。发生的事情被称为Argument-dependent lookup

C++标准允许它。如果要防止ADL,请尝试使用

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

放置圆括号可防止参数相关的查找,请尝试编译器应该抱怨。

编辑:基于OP的编辑

这个答案见阿兰·斯托克斯评论。

+0

我应该更加明确,在主程序中定义了'xs'。我已经编辑了相应的问题。 – korrok

+1

'xs'必须是'std :: vector >'类型,这意味着声明了'Point'的名称空间是一个关联的名称空间,这就是ADL需要的所有东西。 –

+0

Gotcha,我理解现在! – korrok