Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用于头文件中的匿名命名空间_C++_Namespaces_Initialization_Header - Fatal编程技术网

C++ 用于头文件中的匿名命名空间

C++ 用于头文件中的匿名命名空间,c++,namespaces,initialization,header,C++,Namespaces,Initialization,Header,今天有人断言,您不应该在头文件中使用匿名名称空间。通常这是正确的,但我似乎记得有一次有人告诉我,其中一个标准库在头文件中使用匿名名称空间来执行某种初始化 我记得对吗?有人可以填写详细信息吗?我真的看不出在标题中使用匿名名称空间有什么好处。从本质上讲,由于使用相同的符号声明而导致的混乱意味着在包含该头的编译单元中有一个不同的东西,这将是一种过早的、痛苦的脱发 如果是初始化,它很可能是一个iostreams头文件(比如istream,ios,等等)。我认为将匿名名称空间放入头文件没有任何意义。我对标

今天有人断言,您不应该在头文件中使用匿名名称空间。通常这是正确的,但我似乎记得有一次有人告诉我,其中一个标准库在头文件中使用匿名名称空间来执行某种初始化


我记得对吗?有人可以填写详细信息吗?

我真的看不出在标题中使用匿名名称空间有什么好处。从本质上讲,由于使用相同的符号声明而导致的混乱意味着在包含该头的编译单元中有一个不同的东西,这将是一种过早的、痛苦的脱发

如果是初始化,它很可能是一个
iostream
s头文件(比如
istream
ios
,等等)。

我认为将匿名名称空间放入头文件没有任何意义。我对标准和libstdc++头文件进行了灰色搜索,在
元组
头文件(C++1x)中除了一个之外,没有发现任何匿名名称空间:

某些元组的元素在左侧被分配变量(参见),迭代器使用类似的技术。第二个元素被忽略

但正如他们所说,它应该被放入一个.cpp文件中,并且一个实例应该被所有用户共享。他们会在标题中添加声明,如下所示:

extern _Swallow_assign ignore;

在头文件中使用无名名称空间的唯一情况是,您只希望将代码作为头文件分发。例如,Boost的一个大型独立子集纯粹是头部


另一个答案中提到的元组标记
ignore
就是一个例子,
\u 1
\u 2
等。绑定占位符是其他占位符。

我看到它用于为不同翻译单位中的变量提供默认值。但在名称冲突的情况下,这可能会导致意外行为

范例

a.hpp

namespace
{
    const char name[] = "default";
}
// This macro will hide the anonymous variable "name"
#define SET_NAME(newname) \
static const char name[] = newname;
#include "a.hpp"
SET_NAME("file b") // name is "file b" in this translation unit
#include "a.hpp"
SET_NAME("file c") // name is "file c" in this translation unit
#include "a.hpp"
// name is "default" in this translation unit
#include "a.hpp"
static const char name[] = "unintended";
// accidently hiding anonymous name
b.cpp

namespace
{
    const char name[] = "default";
}
// This macro will hide the anonymous variable "name"
#define SET_NAME(newname) \
static const char name[] = newname;
#include "a.hpp"
SET_NAME("file b") // name is "file b" in this translation unit
#include "a.hpp"
SET_NAME("file c") // name is "file c" in this translation unit
#include "a.hpp"
// name is "default" in this translation unit
#include "a.hpp"
static const char name[] = "unintended";
// accidently hiding anonymous name
c.cpp

namespace
{
    const char name[] = "default";
}
// This macro will hide the anonymous variable "name"
#define SET_NAME(newname) \
static const char name[] = newname;
#include "a.hpp"
SET_NAME("file b") // name is "file b" in this translation unit
#include "a.hpp"
SET_NAME("file c") // name is "file c" in this translation unit
#include "a.hpp"
// name is "default" in this translation unit
#include "a.hpp"
static const char name[] = "unintended";
// accidently hiding anonymous name
d.cpp

namespace
{
    const char name[] = "default";
}
// This macro will hide the anonymous variable "name"
#define SET_NAME(newname) \
static const char name[] = newname;
#include "a.hpp"
SET_NAME("file b") // name is "file b" in this translation unit
#include "a.hpp"
SET_NAME("file c") // name is "file c" in this translation unit
#include "a.hpp"
// name is "default" in this translation unit
#include "a.hpp"
static const char name[] = "unintended";
// accidently hiding anonymous name
e.cpp

namespace
{
    const char name[] = "default";
}
// This macro will hide the anonymous variable "name"
#define SET_NAME(newname) \
static const char name[] = newname;
#include "a.hpp"
SET_NAME("file b") // name is "file b" in this translation unit
#include "a.hpp"
SET_NAME("file c") // name is "file c" in this translation unit
#include "a.hpp"
// name is "default" in this translation unit
#include "a.hpp"
static const char name[] = "unintended";
// accidently hiding anonymous name

C++1x?我错过什么了吗?萨特还是叫它C++0x()。等等。。现在我明白他为什么叫我悲观主义者了:)利特和其他一些悲观主义者称之为c++1x。让我们看看谁会赢:pYou不应该为此使用匿名名称空间,因为它们在最终的编译单元中一起崩溃,可能会导致名称空间冲突。取而代之的是,使用一个按照惯例意味着内容是实现细节的名称。例如,Boost使用了
detail
@house,您似乎误解了Boost是如何使用匿名名称空间的<代码>忽略
\u 1
\u 2
等是公共符号-它们不属于
详细信息
。但我同意,对于头库的匿名名称空间,细节名称空间通常是正确的选择。@JamesHopkin总是乐于学习。你能解释为什么_1和_2在匿名名称空间中,而不仅仅是在
名称空间boost
中吗?这会带来什么好处?@thehouse允许仅标题库提供全局对象是一个技巧,这通常会导致链接错误。将对象放入匿名名称空间会强制每个编译单元创建自己的实例。在_1、_2等的情况下,多个实例并不重要,因为它们是无状态的。实现相同效果的另一种方法是使用模板类的静态成员,但是客户端必须键入类似Dummy的内容::_1,而不仅仅是_1。定义
_1
_2
忽略
,,etc将使用
内联变量。请参阅此讨论:这是他从头文件中匿名名称空间获得信息的线程。我在该线程中找不到任何关于在头文件中使用它的信息。有人能解释为什么这是错误的吗?它是否仍然适用于C++11?