Объявление пространства имен как макроса - C ++ - PullRequest
6 голосов
/ 25 февраля 2010

В стандартной библиотеке я обнаружил, что пространство имен std объявлено как макрос.

#define _STD_BEGIN  namespace std {
#define _STD_END        }
  1. Является ли это наилучшей практикой при использовании пространств имен?
  2. Макрос объявлен в Microsoft Visual Studio 9.0\VC\include\yvals.h. Но я не мог найти файлы STL, включая это. Если он не включен, как его можно использовать?

Есть мысли ..?

Ответы [ 5 ]

6 голосов
/ 25 февраля 2010

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

«Но я не смог найти STL-файлы, включая этот. Если он не включен, как его можно использовать?».

Все файлы, которые используют этот макрос, так или иначе включают yvals.h. Например, <vector> включает в себя <memory>, который включает в себя <iterator>, который включает в себя <xutility>, который включает в себя <climits>, который включает в себя <yvals.h>. Цепочка может быть глубокой, но она включает в себя это в какой-то момент.

И я хочу уточнить, это относится только к этой конкретной реализации стандартной библиотеки; это никоим образом не стандартизировано.

3 голосов
/ 25 февраля 2010
  1. В общем, нет. Макросы, вероятно, использовались в то время, когда пространства имен не были реализованы некоторыми компиляторами, или для совместимости с конкретными платформами.
  2. Понятия не имею. Этот файл, вероятно, будет включен другим файлом, который был включен в файл STL.
1 голос
/ 25 февраля 2010

Один подход, который я видел в библиотеке, которую я недавно использовал, был:

BEGIN_NAMESPACE_XXX()

где XXX - количество уровней пространства имен, например:

BEGIN_NAMESPACE_3(ns1, ns1, ns3)

примет три аргумента и расширится до

namespace ns1 {
    namespace ns2 {
        namespace ns2 {

и соответствующий END_NAMESPACE_3 расширится до

        }
    }
}

(для ясности я добавил новые строки и отступы)

1 голос
/ 25 февраля 2010

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

0 голосов
/ 25 февраля 2010

Я мог бы увидеть, как это делается для библиотек C, которые включены в C ++ по ссылке (например, заголовок, который C вызывает string.h, а C ++ - cstring). В этом случае определение макроса будет зависеть от #ifdef _c_plus_plus.

Я бы вообще так не делал. Я не могу придумать ни одного достойного компилятора, который бы не поддерживал пространства имен, исключения, шаблоны или другие «современные» функции C ++ (современный - в кавычках, потому что эти функции были добавлены в середине-конце 90-х). На самом деле, по моему определению, компиляторы стоит использовать, только если они предлагают хорошую поддержку для своего языка. Это не языковая проблема; это простой случай: «если бы я выбрал язык X, я бы предпочел использовать его так, как он существует сегодня, а не так, как он существовал десять или два года назад». Я никогда не понимал, почему некоторые проекты тратят время на поддержку, например, компиляторов до ANSI C.

...