Форум » C/C++ » !Темные места" C++: расширение пространства имен » Ответить

!Темные места" C++: расширение пространства имен

Сыроежка: Стандарт C++ следует читать очень внимательно, вникая в каждое слово написанного. Некоторые параграфы стандарта либо трудно понять, либо не сразу же обращаешь внимание на их смысл, пока не попробуешь с помощью компилятора или компиляторов осмыслить и проверить написанное. Одно из таких "темных мест", которому при первом чтении можно не придать значение, касается расширения пространства имен. В самом начале раздела "9.7.1 Namespace definition" стандарта C++ 20 имеется следующий параграф [quote]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. [/quote] Вы поняли, что написано? А из написанного вытекает следующее. Вы можете объявить пространство имен внутри множества он-лайновых пространств заданного пространства, а затем расширить его в заданном замыкающем пространстве вне множества от-лайновых пространств имен. Чтобы было более понятно, приведу следующую демонстрационную программу. [pre2] #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' ); }[/pre2] Ее вывод на консоль: [pre2] f( int ) f( char )[/pre2] Как видно из текста программы, пространство имен N3 было объявлено в он-лайновом пространстве имен N2 пространства имен N1. А затем пространство имен N3 было расширено, но его расширение помещено не в пространство имен N2, а непосредственно в пространство имен N1. Такое расширение допустимо. Однако, если сначала поместить пространство имен N3 внутрь пространства имен N1, а затем расширение пространства имен N3 вложить в он-лайновое пространство имен N2, то соответствующая программа уже не будет компилироваться. [pre2] #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' ); }[/pre2] Компилятор сообщит о неоднозначности имени N3. Чтобы понять суть происходящего, то следует запомнить, что объявления в он-лайновых пространствах имен являются объявлениями и его замыкающего пространства. В то время как, объявления замыкающего пространства не являются объявлениями его он-лайновых вложенных пространств.

Ответов - 0



полная версия страницы