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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/357564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:53:49  来源:igfitidea点击:

Uses for anonymous namespaces in header files

c++namespacesinitializationheader

提问by David Norman

Someone asserted on SO today that you should never use anonymous namespaces in header files. Normally this is correct, but I seem to remember once someone told me that one of the standard libraries uses anonymous namespaces in header files to perform some sort of initialization.

今天有人在 SO 上断言,你永远不应该在头文件中使用匿名命名空间。通常这是正确的,但我似乎记得曾经有人告诉我标准库之一使用头文件中的匿名命名空间来执行某种初始化。

Am I remembering correctly? Can someone fill in the details?

我没记错吗?有人可以填写详细信息吗?

采纳答案by James Hopkin

The only situation in which a nameless namespace in header can be useful is when you want to distribute code as header files only. For example, a large standalone subset of Boost is purely headers.

header 中的无名命名空间唯一有用的情况是当您只想将代码作为头文件分发时。例如,Boost 的一个大型独立子集纯粹是标题。

The token ignorefor tuples, mentioned in another answer is one example, the _1, _2etc. bind placeholders are others.

ignore在另一个答案中提到的元组标记是一个例子_1_2等 绑定占位符是其他的。

回答by Johannes Schaub - litb

I don't see any point in putting an anonymous namespace into a header file. I've grepped the standard and the libstdc++ headers, found no anonymous namespaces apart of one in the tupleheader (C++1x stuff):

我认为将匿名命名空间放入头文件没有任何意义。我已经搜索了标准和 libstdc++ 标头,发现除了tuple标头中的一个(C++1x 东西)之外没有任何匿名命名空间:

  // A class (and instance) which can be used in 'tie' when an element
  // of a tuple is not required
  struct _Swallow_assign
  {
    template<class _Tp>
      _Swallow_assign&
      operator=(const _Tp&)
      { return *this; }
  };

  // TODO: Put this in some kind of shared file.
  namespace
  {
    _Swallow_assign ignore;
  }; // anonymous namespace

This is so you can do

这是你可以做的

std::tie(a, std::ignore, b) = some_tuple;

elements of the some_tuple are assigned the variables at the left side (see here), a similar technique is used for thisiterator. The second element is ignored.

some_tuple 的元素被分配到左侧的变量(见这里),这个迭代器使用了类似的技术。第二个元素被忽略。

But as they say, it should be put into a .cpp file and the one instance should be shared by all users. They would put a declaration of it into the header like this then:

但正如他们所说,它应该被放入一个 .cpp 文件中,并且一个实例应该被所有用户共享。他们会像这样将它的声明放入标题中:

extern _Swallow_assign ignore;

回答by Jacqui Gurto

I've seen it used to provide a default value for a variable in different translation units. But it could cause unexpected behaviour in the case of name clashes.

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

Example

例子

a.hpp

一个.hpp

namespace
{
    const char name[] = "default";
}
// This macro will hide the anonymous variable "name"
#define SET_NAME(newname) \
static const char name[] = newname;

b.cpp

b.cpp

#include "a.hpp"
SET_NAME("file b") // name is "file b" in this translation unit

c.cpp

cpp

#include "a.hpp"
SET_NAME("file c") // name is "file c" in this translation unit

d.cpp

d.cpp

#include "a.hpp"
// name is "default" in this translation unit

e.cpp

e.cpp

#include "a.hpp"
static const char name[] = "unintended";
// accidently hiding anonymous name

回答by Jon Trauntvein

I really can see no positive benefit from using anonymous namespaces in headers. The confusion that can result from having the same symbol declaration mean, in essence, a different thing in the compilation units that include that header would be a guaranteed way to go prematurely and painfully bald.

我真的看不出在标题中使用匿名命名空间没有任何积极的好处。具有相同符号声明可能导致的混淆意味着,本质上,包含该头文件的编译单元中的不同内容将是一种有保证的过早和痛苦的秃头方式。

回答by Max Lybbert

If it's initialization, it would likely be an iostreams header (like istream, ios, etc.).

如果它的初始化,这可能会是一个iostream头球(如istreamios等)。