1 #include <iostream>
2
3 namespace primerlib {
4 void compute() { std::cout << "primerlib::print()" << std:: endl; }
5 void compute(const void *p) { std::cout << "primerlib::print(const void *p)" << std:: endl; }
6 }
7
8 //using primerlib::compute;
9 //using namespace primerlib;
10 void compute(int a) { std::cout << "::compute(int)" << std:: endl; }
11 void compute(double d, double dd=3.4) { std::cout << "primerlib::compute(d, d)" << std:: endl; }
12 void compute(char* p, char* p1 = 0) { std::cout << "primerlib::compute(char*, char*)" << std:: endl; }
13
14 int main(void)
15 {
16 using primerlib::compute;
17 //using namespace primerlib;
18 compute(0);
19 return 0;
20 }
输出:
primerlib::print(const void *p)
我的问题是为什么它没有调用全局计算(int)?如果我在第17行使用using指令,它将调用compute(int)。非常感谢您的帮助。
答案 0 :(得分:4)
这是因为using namespace X
和using X::Y
的工作方式不同。使用using namespace X
时,在名称查找期间会考虑该命名空间中的所有内容。请考虑以下示例:
namespace A
{
void foo(int){}
}
namespace B
{
void foo(int){}
}
using namespace A;
using namespace B;
int main()
{
foo(1);
}
此处,在名称查找期间将考虑A
和B
成员,并且您将遇到call of overloaded foo(int) is ambiguous
错误,因为编译器无法确定两个函数中的哪一个使用,因为它们是相同的。 using X::Y
语法旨在解决此问题。当您使用它时,您告诉编译器仅使用Y
命名空间中的X
,而不考虑其他任何内容。我们将其添加到上面的示例中:
namespace A
{
void foo(int){}
}
namespace B
{
void foo(int){}
}
using namespace A;
using namespace B;
int main()
{
using A::foo;
foo(1);
}
这里我们告诉编译器使用foo
命名空间中找到的A
实例,并忽略范围内的任何其他foo
。因此,在您的示例中,您告诉编译器仅使用primerlib::compute
,如果要从全局范围访问函数,则必须使用::compute()
,并调用compute(int)
}。
答案 1 :(得分:1)
使用primerlib :: compute;
这是using
声明。当您使用它时,就好像在声明的位置声明了一个名称。您可以通过添加foo
(或使用全局范围using ::foo;
调用全局::foo(0);
来恢复全局::compute(int)
,您将在输出中看到foo
。
在您的示例编译器中未找到全局using declaration
声明的事实是因为这是名称查找的工作方式 - 它会在找到名称后搜索封闭的范围和stope。
有关使用声明的更多参考,请参阅:http://en.cppreference.com/w/cpp/language/namespace#Using-declarations
[编辑]
我误解了你的问题,在第17行你有'使用指令',它的行为与 foreach ($array as $key => $value)
{
if ((isset($array[$key+1)) && ($array[$key]['released'] === false && ($array[$key+1]['released'] === false)){
unset($array[$key]);
}
}
return $array;
不同,它没有在最近的封闭声明区域(在你的情况下是它的主函数)中引入名称,但添加了名称到最近的封闭命名空间 - 在这个演员表中它是全局命名空间。有关更多参考:http://en.cppreference.com/w/cpp/language/namespace#Using-directives:
只允许在命名空间范围和块范围内使用using指令。从使用指令之后的任何名称的非限定名称查找的角度来看,直到它出现的作用域的结尾, 来自namespace-name的每个名称都是可见的,就像它在最近的封闭命名空间 ,其中包含using-directive和namespace-name。
使用-directive不会向显示的声明区域添加任何名称 (与using-declaration不同),因此不会阻止相同的名称声明。
答案 2 :(得分:0)
使用实际的using声明,你说compute是一个只引用namespace primerlib中定义的函数的名称:实际上如果你试图调用接受double的compute函数,你会得到一个没有匹配函数的错误。 使用注释使用声明,您可以为所有计算功能提供相同的重要性&#34;:引用全局计算功能,您必须使用&#34; ::&#34;命名空间解析指令,要引用引号的命名空间,你必须使用&#34; primerlib ::&#34;命名空间解析指令。
答案 3 :(得分:0)
using directive
和using declaration
会有所不同。
7.3.4 $ 2使用指令[namespace.udir] :(由我粗体)
using-directive指定指定名称空间中的名称 可以在using指令出现的范围内使用 使用指令。在非限定名称查找(3.4.1)期间,名称 看起来好像是在最近的封闭命名空间中声明的 它包含using-directive和指定的命名空间。 [ 注意:在此上下文中,“包含”表示“直接包含或 间接地”。 - 后注]
在这种情况下,最近的封闭命名空间是全局namaspace,命名空间primerlib
的函数与其他全局函数出现在同一命名空间中,因此在调用重载分辨率::compute(int)
之后。
7.3.3 $ 1使用声明[namespace.udecl]:
using声明在声明区域中引入了一个名称 其中出现了使用声明。
命名空间primerlib
的函数将被引入main
函数范围,它们将在具有高优先级的名称查找阶段被选中,然后名称查找将停止。全局函数不会考虑重载分辨率,因此调用了primerlib::compute(const void *p)
。
顺便说一句:如果您将using primerlib::compute;
移出main
功能,您将获得与在using namespace primerlib;
函数中使用main
相同的结果。