名称空间和作用域可见性问题
Namespaces and scope visibility issue
我制作了一个头文件sampleheader.h
,代码如下:
namespace sample_namespace
{
int add(int n1,int n2)
{
return (n1 + n2);
}
}
现在我的main.cpp文件是:
#include <iostream>
#include "sampleheader.h"
using namespace std;
int add(int n1, int n2)
{
return (n1 + n2);
}
int main(void)
{
using namespace sample_namespace;
//cout<<add(5,7);
}
如果我留下注释行,项目将在没有警告的情况下构建。这是可以理解的,因为局部add()
函数是在全局作用域中定义的,而add()
函数是在main()作用域中可见的。因此不会发生名称冲突。
然而,如果我删除注释,我得到以下错误:
"Ambiguous call to overloaded function"
首先,不应该有任何名称冲突,正如我上面解释的那样(如果我是对的)。但是,如果有一个名称冲突,为什么它是由编译器通知只有当我调用函数。这种类型的错误应该在名称冲突时立即显示(如果有的话)。
好吧,你自己解释了。
当int add()
和int sample_namespace::add()
都在作用域中时,调用是不明确的。语句add()
可以表示它们中的任何一个。
共存的函数不存在冲突,因为一个是int add()
,另一个是int sample_namespace::add()
。这就是命名空间的全部目的。
你只需要在编写使用它们的代码时弄清楚。如果你摆脱了using namespace
指令,总是写显式代码,那么你就不会遇到问题:
#include <iostream>
namespace sample_namespace {
int add(int n1, int n2) {
return (n1 + n2);
}
}
int add(int n1, int n2) {
return (n1 + n2);
}
int main() {
std::cout << sample_namespace::add(5,7);
}
(另外,在头文件中定义非内联函数是一个坏主意)
"using namespace"不隐藏其他实现。在这种情况下,它所做的是使它具有二义性。
sample_namespace::add和::add具有相同的签名。由于您没有明确地说明使用哪一个,编译器无法判断。
声明两个函数都是合法且明确的(这就是为什么当你使用该函数时编译器只会报错)。
这样声明两个函数是合法的原因是,通过限定它们,可以明确地调用它们。这就是为什么只有在进行非限定调用时才会得到错误。到目前为止,根本不存在理论问题。
有意地,using namespace X;
不应该自己引入歧义错误。这将大大破坏名称空间的目的。通用的using namespace std;
引入了许多您自己也可以合理定义的名称。
你不能像那样遮蔽符号,只能遮蔽变量名(这在大多数编译器上是一个警告,即一个坏主意)。using指令在任何意义上都是不精确的,我认为这是大多数人的假设。
using指令将把一个符号导入到作用域中。例如,您可以这样做:
namespace foo {
using namespace std;
}
foo::string val;
这种做法会导致一些非常恼人的编译器错误。您的简单示例很清楚错误在哪里。如果你试着用几十万行代码来做这件事,你就不会那么高兴了。
我建议你不要养成依赖using指令的习惯。如果必须的话,一次只做一种类型。
using std::string;
基本上,这让你诚实。如果有命名冲突,grep将花费30秒来发现问题在。
如果你只花几周时间在你的类型前面输入std::,你会习惯的。
我认为这是因为编译器优化。当你的字符串被注释-他看到,有一些函数,但你不使用它,所以他丢弃它。当他看到这个函数很有用的时候——他想插入函数调用,但是不能选择你想要的那个
- C++quit()函数中可能存在作用域问题
- 操作员新实施可见性问题
- 无锁的堆栈:在POP()期间检查危险指针时可见性问题
- 作用域问题:如何从类外查看(不访问也不修改!)私有属性
- C++指针到指针作用域的问题
- 为什么编译器对此模板存在作用域问题
- 将对象的属性传递到方法时出现作用域问题.(opencv相关)
- 基类的复制构造函数的可见性问题
- C++线程与可见性问题 - 常见的工程实践是什么?
- 全局变量和枚举之间的作用域问题
- 遇到getline、fstream、作用域不一致的问题
- c++双删除文件作用域变量,链接问题
- 类中vector的作用域问题
- 模板作用域问题代码无法编译
- 构造函数排序(全局作用域)问题
- Make_shared在try catch作用域问题中
- c++作用域问题:创建一个矩阵类而不浪费空间
- 关于作用域的一般编程问题
- 当结构未解析为类型和作用域问题时的c++错误
- 名称空间和作用域可见性问题