Используется для анонимных пространств имен в заголовочных файлах - PullRequest
45 голосов
/ 10 декабря 2008

Сегодня кто-то заявил на SO, что вы никогда не должны использовать анонимные пространства имен в заголовочных файлах. Обычно это правильно, но я помню, как однажды кто-то сказал мне, что одна из стандартных библиотек использует анонимные пространства имен в заголовочных файлах для выполнения некоторой инициализации.

Я правильно помню? Может кто-нибудь заполнить детали?

Ответы [ 5 ]

23 голосов
/ 11 декабря 2008

Единственная ситуация, в которой безымянное пространство имен в заголовке может быть полезно, - это когда вы хотите распространять код только как файлы заголовков. Например, большое автономное подмножество Boost - это просто заголовки.

Токен ignore для кортежей, упомянутый в другом ответе, является одним примером, _1, _2 и т.д.

14 голосов
/ 11 декабря 2008

Я не вижу смысла помещать анонимное пространство имен в заголовочный файл. Я собрал стандартные и заголовки 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 присваиваются переменные слева (см. здесь ), аналогичная техника используется для этого итератора. Второй элемент игнорируется.

Но, как говорится, он должен быть помещен в файл .cpp, и один экземпляр должен быть доступен всем пользователям. Тогда они поместили бы объявление об этом в заголовок следующим образом:

extern _Swallow_assign ignore;
5 голосов
/ 08 сентября 2015

Я видел, как он использовался для предоставления значения по умолчанию для переменной в разных единицах перевода. Но это может вызвать неожиданное поведение в случае столкновения имен.

Пример

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
2 голосов
/ 11 декабря 2008

Я действительно не вижу никакой положительной выгоды от использования анонимных пространств имен в заголовках. Путаница, которая может возникнуть в результате использования одного и того же объявления символа, по сути, означает, что в единицах компиляции, включающих этот заголовок, будет иная вещь, которая будет гарантированно преждевременной и болезненной лысиной.

0 голосов
/ 11 декабря 2008

Если это инициализация, это, вероятно, будет заголовок iostream s (например, istream, ios и т. Д.).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...