重复两条评论。
在两个版本之间(一:两个独立的命名空间,二:嵌套的命名空间),名称查找存在一些差异。其中大部分可以通过使用声明(例如using outer::function0;
)或使用指令(例如using namespace library1;
)来克服,但有些不能。
1.内部命名空间内的非限定查找
#include <iostream>
namespace outer
{
void function0() { std::cout << "outer::function0" << std::endl; }
namespace inner
{
void test0()
{
function0(); // finds outer::function
}
}
}
namespace another_outer
{
void test0_1()
{
// either
using namespace outer;
// or
using outer::function0;
function0();
}
}
注意,您也可以将using-directive或using-declaration放在命名空间范围内another_outer
,但仍有一些区别:
2.停止不合格的查找
一旦找到名称,不合格的查找就会在一个范围内停止(然后不搜索外部范围)。这可用于隐藏其他范围的功能。这是与此相关的问题的示例;也看到这个答案。
void function1() { std::cout << "::function1" << std::endl; }
namespace another_outer
{
void function1() { std::cout << "another_outer::function1" << std::endl; }
}
namespace outer
{
namespace inner
{
void function1() { std::cout << "outer::inner::function1" << std::endl; }
}
void test1()
{
function1(); // finds ::function1
{
using namespace inner;
function1(); // finds (only) outer::inner::function1
}
{
using namespace another_outer;
//function1(); // finds both ::function1 and another_outer::function1
// error: ambiguous call
}
}
}
3. 日常生活
这与两个变体之间的差异无关,而是解决“在第二种情况下我必须完全限定符号,对吗?”。当您不限定函数调用中的函数名称时,会发生与参数相关的查找。它在与参数关联的命名空间(和类)中查找函数的名称。
namespace outer
{
struct ADL {};
void function2(ADL&) { std::cout << "outer::function2" << std::endl; }
namespace inner
{
void function2(ADL const&);
void test2()
{
ADL x;
function2(x); // finds both outer::function2
// and outer::inner::function2
// overload resolution selects outer::function2
}
}
}
int main()
{
outer::ADL x;
function2(x); // finds outer::function2
outer::inner::test2();
// other tests:
outer::inner::test0();
outer::test1();
}
4. 特别是关于冲突的符号
如果您有两个相同的函数(返回类型除外),outer
并且outer::inner
在某个调用中找到了两者,则该调用将是模棱两可的。但是不合格的查找可能只能找到其中之一:
namespace outer
{
void function3() { std::cout << "outer::function3()" << std::endl; }
namespace inner
{
void function3()
{ std::cout << "outer::inner::function3()" << std::endl; }
void test3()
{
function3(); // only finds outer::inner::function3
}
}
void test3_1()
{
using namespace inner;
//function3(); // finds both outer::function3
// and outer::inner::function3
// error: ambiguous call
using inner::function3;
function3(); // finds (only) outer::inner::function3
}
}
namespace another_outer
{
void function3() { std::cout << "another_outer::function3" << std::endl; }
void test3_1()
{
using namespace outer;
function3(); // still only finds another_outer::function3
using outer::function3;
function3(); // only finds outer::function3
}
}