C++ 在哪里使用带有转换单元的声明,在名称空间内部还是外部?
我读过关于名称空间的文章,但没有找到答案 例如:C++ 在哪里使用带有转换单元的声明,在名称空间内部还是外部?,c++,namespaces,C++,Namespaces,我读过关于名称空间的文章,但没有找到答案 例如: // example1.cpp #include "example1.h" #include <set> namespace MyNamespace { using std::set; void f() {}; } // example2.cpp #include "example2.h" #include <set> using std::set; namespace MyNamespace
// example1.cpp
#include "example1.h"
#include <set>
namespace MyNamespace
{
using std::set;
void f() {};
}
// example2.cpp
#include "example2.h"
#include <set>
using std::set;
namespace MyNamespace
{
void f() {};
}
//示例1.cpp
#包括“示例1.h”
#包括
名称空间MyNamespace
{
使用std::set;
void f(){};
}
//例2.cpp
#包括“示例2.h”
#包括
使用std::set;
名称空间MyNamespace
{
void f(){};
}
这两个例子都是我们位于某个x?翻译单位,我的项目是使用名称空间MyNamespace
我觉得第二个例子更好,但不知道为什么,因为我在其他翻译单元中看不到导入的名称std::set
?那么,我为什么要费心在Mynamespace外部还是内部使用std::set调用
你能解释一下吗?
另外,在哪个点将std::set
导入Mynamespace
?你怎么知道
编辑:
假设abowe to示例是同一项目的cpp文件,那么导入std::set内部或外部MyNamespace是等效的,因为其他cpp文件(位于同一命名空间中)无论如何都看不到名称集(即使您#包含并使用名称空间MyNamespace键入,也没有效果。您必须在每个翻译单元中使用std::set键入如果您想使用set I'm I correct,为什么?首先将符号名std::set
仅导入MyNamespace
,而,
第二步将其导入到当前名称空间,在该名称空间中写入using声明(在所示示例中,这恰好是全局范围)
您应该为using指令的编写位置而烦恼,因为符号名随后只导入到编写它的当前名称空间中,而在其他作用域中它将不可见
我不理解问题的这一部分,在哪一点将导入std::set
,这一点与什么有关?在第一个示例中,std::set中的对象、类和方法可以在您的命名空间(MyNamespace)中显式访问
然而,在第二个示例中,std::set中的对象、类和方法在任何地方都是明确可用的(在MyNamespace内部和外部)
例如,在伪代码中(不要照字面理解)
//exmaple1.cpp
//包括在这里
使用名称空间std;
名称空间MyNamespace{
//使用cout的示例
//可以在这里显式调用cout,如下所示
CUT 记住,在C++中,不同的源文件通常会产生不同的翻译单位。
非正式地说,翻译单元是包含文件的结果,您可以使用
-E
(使用gcc和clang)来转储预处理的输出
现在,翻译单元在编译阶段是相互独立的。因此,在其中一个单元中执行的任何操作对其他单元都绝对没有影响。这显然适用于使用
指令的
当然,有一些头文件可以帮助您共享
要明确的是:
// foo.hpp
#include <set>
namespace Foo { using std::set; }
// foo.cpp
#include "foo.hpp"
namespace Foo {
using std::swap;
// both set and swap are accessible without further qualification
}
// bar.cpp
#include "foo.hpp"
namespace Foo {
// set is accessible without further qualification, swap is not.
}
//foo.hpp
#包括
命名空间Foo{使用std::set;}
//foo.cpp
#包括“foo.hpp”
名称空间Foo{
使用std::swap;
//set和swap都可以访问,无需进一步限定
}
//bar.cpp
#包括“foo.hpp”
名称空间Foo{
//集合无需进一步限定即可访问,交换不可用。
}
应该注意的是,最好避免在全局命名空间中引入名称。无论是新类型、函数、typedef
还是通过使用
指令。这样可以避免冲突:)确保在发布代码之前先测试代码。“使用std”不起作用。另外,最好使用OP的示例,即std::set。在一个cpp中,我使用std::set键入,但在同一名称空间中的另一个翻译单元中,我看不到set。因此,无论在名称空间内还是在名称空间外键入,似乎没有区别,因为您不会从另一个名称中看到该名称cpp文件…它就像一个静态变量,我是对的?非常感谢!事实上,这个示例和您的上一句话回答了我的问题:)@codekiddy:除了你的问题之外,我还冒昧地对Als的答案发表了评论:)+1,因为我创建了一个很好的代码示例,该示例在我的答案的评论中解决了OP的问题。不幸的是,我被一些事情缠住了(代码审查会议:-])直到大约一分钟前,我才注意到这个问题的评论,但这非常准确地回答了这个问题。@Als:当你的工作生活侵蚀了你的生活时,你不讨厌吗?
// foo.hpp
#include <set>
namespace Foo { using std::set; }
// foo.cpp
#include "foo.hpp"
namespace Foo {
using std::swap;
// both set and swap are accessible without further qualification
}
// bar.cpp
#include "foo.hpp"
namespace Foo {
// set is accessible without further qualification, swap is not.
}