Проблемы с пространством имен в C ++ 11?

Может кто-нибудь объяснить, пожалуйста, следующее:

$ cat test.cpp
#include <string>
std::string div;
$ g++ -c test.cpp
$ g++ -std=c++11 -c test.cpp
test.cpp:2:13: error: 'std::string div' redeclared as different kind of symbol
In file included from /usr/include/c++/4.7.1/cstdlib:66:0,
from /usr/include/c++/4.7.1/ext/string_conversions.h:37,
from /usr/include/c++/4.7.1/bits/basic_string.h:2814,
from /usr/include/c++/4.7.1/string:54,
from test.cpp:1:
/usr/include/stdlib.h:787:14: error: previous declaration of 'div_t div(int, int)'
$

Не должен div символ быть в std пространство имен также для режима C ++ 11? Или это что-то особенное для моей системы?

8

Решение

/usr/include/stdlib.h

Каждое имя в .h Заголовок C stdlib находится в глобальном пространстве имен (очевидно).

Кроме того, любой cHEADER Заголовок C ++ stdlib определит соответствующие имена из HEADER.h в std пространство имен, но также разрешено иметь их в глобальном пространстве имен (так что они могут просто сделать

// cHEADER
#include <HEADER.h>

namespace std{
using ::one_name_from_HEADER;
using ::another_name_from_HEADER;
// and so on...
}

и покончим с этим).

§D.5 [depr.c.headers]

p2 Каждый заголовок C, каждый из которых имеет имя вида name.h, ведет себя так, как будто каждое имя помещено в стандартное пространство имен библиотеки cname заголовок помещается в глобальную область имен. Не указано, были ли эти имена сначала объявлены или определены в пределах области имен (3.3.6) пространства имен std, а затем введены в глобальную область имен с помощью явных объявлений using (7.3.3).

p3 [ Пример: Заголовок <cstdlib> несомненно, предоставляет свои объявления и определения в пространстве имен std. Он также может предоставлять эти имена в глобальном пространстве имен. Заголовок <stdlib.h> несомненно, обеспечивает те же объявления и определения в глобальном пространстве имен, что и в стандарте C. Он также может предоставлять эти имена в пространстве имен std. — конец примера ]

Как видите, то же самое верно и наоборот (<HEADER.h> май вводит имена в std пространство имен, как будто

// HEADER.h
#include <cHEADER>

using std::one_name_from_HEADER;
using std::another_name_from_HEADER;
// and so on...
}

), что делает различие между этими заголовками довольно … бесполезным, на самом деле.

4

Другие решения

div это функция от <stdlib.h>,

В C ++ 11 <cвздор> заголовкам было разрешено размещать вещи в глобальном пространстве имен.

C ++ 11 §17.6.1.2 / 4:
«За исключением случаев, указанных в пунктах 18–30 и Приложении D, содержание каждого заголовка cname должно быть таким же
как у соответствующего заголовка name.h, как указано в стандартной библиотеке C (1.2) или C Unicode TR, в зависимости от случая, как если бы это было сделано путем включения. В стандартной библиотеке C ++, однако, объявления (за исключением
имена, которые определены как макросы в C), находятся в пределах области имен (3.3.6) пространства имен std, это
не указано, будут ли эти имена сначала объявлены в глобальной области имен, а затем введены
в пространство имен STD явным с помощью деклараций (7.3.3) «.

Отражение реальности распространенных реализаций C ++.

Так что, на самом деле, ничего не изменилось, кроме формального: то, что вы видите, теперь наказывается стандартом, а не является артефактом реализации, который нужно учитывать.

Кроме того, формальное изменение облегчает спор о том, что лучше .h заголовки, а не cххх заголовки …

3

17.6.4.3.3 / 1 гласит:

Каждое имя, объявленное как объект с внешней связью в заголовке, зарезервировано для реализации, чтобы обозначить этот объект библиотеки с внешней связью,182 оба в пространстве имен std и в глобальном пространстве имен.

div это имя, объявленное как функция с внешней связью в заголовке cstdlib, и, следовательно, зарезервированное имя в глобальном пространстве имен. Вам не разрешено использовать это имя.

1
По вопросам рекламы [email protected]