用于头文件中的匿名名称空间

时间:2008-12-10 20:49:11

标签: c++ namespaces initialization header

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

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

5 个答案:

答案 0 :(得分:23)

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

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

答案 1 :(得分:14)

我认为将匿名命名空间放入头文件中没有任何意义。我已经使用了标准和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

这是你可以做的

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

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

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

extern _Swallow_assign ignore;

答案 2 :(得分:5)

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

实施例

<强> a.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

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

<强> c.cpp

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

<强> d.cpp

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

<强> e.cpp

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

答案 3 :(得分:2)

我真的看不到在标头中使用匿名命名空间的好处。具有相同符号声明可能导致的混淆本质上意味着包含该标题的编译单元中的不同内容将是过早且痛苦地秃顶的保证方式。

答案 4 :(得分:0)

如果是初始化,则可能是iostream标头(如istreamios等)。