On-line: гостей 0. Всего: 0 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 23.10.19 21:40. Заголовок: !Темные места" C++: расширение пространства имен


Стандарт C++ следует читать очень внимательно, вникая в каждое слово написанного. Некоторые параграфы стандарта либо трудно понять, либо не сразу же обращаешь внимание на их смысл, пока не попробуешь с помощью компилятора или компиляторов осмыслить и проверить написанное.

Одно из таких "темных мест", которому при первом чтении можно не придать значение, касается расширения пространства имен. В самом начале раздела "9.7.1 Namespace definition" стандарта C++ 20 имеется следующий параграф

 цитата:
2 In a named-namespace-definition, the identifier is the name of the namespace. If the identifier, when looked
up (6.4.1), refers to a namespace-name (but not a namespace-alias) that was introduced in the namespace in
which the named-namespace-definition appears or that was introduced in a member of the inline namespace
set of that namespace, the namespace-definition extends the previously-declared namespace. Otherwise, the
identifier is introduced as a namespace-name into the declarative region in which the named-namespace definition appears.



Вы поняли, что написано? А из написанного вытекает следующее. Вы можете объявить пространство имен внутри множества он-лайновых пространств заданного пространства, а затем расширить его в заданном замыкающем пространстве вне множества от-лайновых пространств имен.

Чтобы было более понятно, приведу следующую демонстрационную программу.

 
#include <iostream>

inline namespace N1
{
inline namespace N2
{
namespace N3
{
void f( int ) { std::cout << "f( int )\n"; }
}
}

namespace N3
{
void f( char ) { std::cout << "f( char )\n"; }
}
}

int main()
{
N3::f( 10 );
N2::N3::f( 'A' );
}

Ее вывод на консоль:
 
f( int )
f( char )


Как видно из текста программы, пространство имен N3 было объявлено в он-лайновом пространстве имен N2 пространства имен N1.
А затем пространство имен N3 было расширено, но его расширение помещено не в пространство имен N2, а непосредственно в пространство имен N1.

Такое расширение допустимо.

Однако, если сначала поместить пространство имен N3 внутрь пространства имен N1, а затем расширение пространства имен N3 вложить в он-лайновое пространство имен N2, то соответствующая программа уже не будет компилироваться.
 
#include <iostream>

inline namespace N1
{
namespace N3
{
void f( char ) { std::cout << "f( char )\n"; }
}

inline namespace N2
{
namespace N3
{
void f( int ) { std::cout << "f( int )\n"; }
}
}

}

int main()
{
N3::f( 10 );
N2::N3::f( 'A' );
}

Компилятор сообщит о неоднозначности имени N3.

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

Спасибо: 0 
ПрофильЦитата Ответить
Новых ответов нет


Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 31
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет