Главная » Просмотр файлов » B. Stroustrup - The C++ Programming Language

B. Stroustrup - The C++ Programming Language (794319), страница 90

Файл №794319 B. Stroustrup - The C++ Programming Language (B. Stroustrup - The C++ Programming Language) 90 страницаB. Stroustrup - The C++ Programming Language (794319) страница 902019-05-09СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 90)

Then, Idon’t have to remember two different names for the same entity. However, sometimes a new nameis needed or simply nice to have. For example:namespace Lib2 {using namespace His_lib;using namespace Her_lib;using His_lib::String;using Her_lib::Vector;// everything from His_lib// everything from Her_lib// resolve potential clash in favor of His_lib// resolve potential clash in favor of Her_lib410NamespacesChapter 14using Her_string = Her_lib::String;template<class T>using His_vec = His_lib::Vector<T>;template<class T>class List { /* ... */ };// ...// rename// rename// additional stuff}There is no general language mechanism for renaming, but for types and templates, we can introduce aliases with using (§3.4.5, §6.5).14.4.5 Namespaces and OverloadingFunction overloading (§12.3) works across namespaces.

This is essential to allow us to migrateexisting libraries to use namespaces with minimal source code changes. For example:// old A.h:void f(int);// ...// old B.h:void f(char);// ...// old user.c:#include "A.h"#include "B.h"void g(){f('a'); // calls the f() from B.h}This program can be upgraded to a version using namespaces without changing the actual code:// new A.h:namespace A {void f(int);// ...}// new B.h:namespace B {void f(char);// ...}Section 14.4.5Namespaces and Overloading411// new user.c:#include "A.h"#include "B.h"using namespace A;using namespace B;void g(){f('a');}// calls the f() from B.hHad we wanted to keep user.c completely unchanged, we would have placed the using-directives inthe header files. However, it is usually best to avoid using-directives in header files, becauseputting them there greatly increases the chances of name clashes.This overloading rule also provides a mechanism for extending libraries.

For example, peopleoften wonder why they have to explicitly mention a sequence to manipulate a container using astandard-library algorithm. For example:sort(v.begin(),v.end());Why not write:sort(v);The reason is the need for generality (§32.2), but manipulating a container is by far the most common case. We can accommodate that case like this:#include<algorithm>namespace Estd {using namespace std;template<class C>void sort(C& c) { std::sort(c.begin(),c.end()); }template<class C, class P>void sort(C& c, P p) { std::sort(c.begin(),c.end(),p); }}Estd (my ‘‘extended std’’) provides the frequently wanted container versions of sort().

Those are ofcourse implemented using std::sort() from <algorithm>. We can use it like this:using namespace Estd;template<class T>void print(const vector<T>& v){for (auto& x : v)cout << v << ' ';cout << '\n';}412NamespacesChapter 14void f(){std::vector<int> v {7, 3, 9, 4, 0, 1};sort(v);print(v);sort(v,[](int x, int y) { return x>y; });print(v);sort(v.begin(),v.end());print(v);sort(v.begin(),v.end(),[](int x, int y) { return x>y; });print(v);}The namespace lookup rules and the overloading rules for templates ensure that we find and invokethe correct variants of sort() and get the expected output:013479974310013479974310If we removed the using namespace std; from Estd, this example would still work because std’ssort()s would be found by argument-dependent lookup (§14.2.4).

However, we would then not findthe standard sort()s for our own containers defined outside std.14.4.6 VersioningThe toughest test for many kinds of interfaces is to cope with a sequence of new releases (versions).Consider a widely used interface, say, an ISO C++ standard header. After some time, a new version is defined, say, the C++11 version of the C++98 header. Functions may have been added,classes renamed, proprietary extensions (that should never have been there) removed, typeschanged, templates modified. To make life ‘‘interesting’’ for the implementer, hundreds of millionsof lines of code are ‘‘out there’’ using the old header, and the implementer of the new version cannot ever see or modify them. Needless to say, breaking such code will cause howls of outrage, aswill the absence of a new and better version.

The namespace facilities described so far can be usedto handle this problem with very minor exceptions, but when large amounts of code are involved,‘‘very minor’’ still means a lot of code. Consequently, there is a way of selecting between two versions that simply and obviously guarantees that a user sees exactly one particular version. This iscalled an inline namespace:namespace Popular {inline namespace V3_2 { // V3_2 provides the default meaning of Populardouble f(double);int f(int);template<class T>class C { /* ...

*/ };}Section 14.4.6Versioning413namespace V3_0 {// ...}namespace V2_4_2 {double f(double);template<class T>class C { /* ... */ };}}Here, Popular contains three subnamespaces, each defining a version. The inline specifies that V3_2is the default meaning of Popular. So we can write:using namespace Popular;void f(){f(1);V3_0::f(1);V2_4_2::f(1);}// Popular ::V3_2::f(int)// Popular ::V3_0::f(double)// Popular ::V2_4_2::f(double)template<class T>Popular::C<T∗> { /* ... */ };This inline namespace solution is intrusive; that is, to change which version (subnamespace) is thedefault requires modification of the header source code. Also, naively using this way of handlingversioning would involve a lot of replication (of common code in the different versions).

However,that replication can be minimized using #include tricks. For example:// file V3_common:// ... lots of declarations ...// file V3_2:namespace V3_2 { // V3_2 provides the default meaning of Populardouble f(double);int f(int);template<class T>class C { /* ... */ };#include "V3_common"}// file V3_0.h:namespace V3_0 {#include "V3_common"}414NamespacesChapter 14// file Popular.h:namespace Popular {inline#include "V3_2.h"#include "V3_0.h"#include "V2_4_2.h"}I do not recommend such intricate use of header files unless it is really necessary.

The exampleabove repeatedly violates the rules against including into a nonlocal scope and against having asyntactic construct span file boundaries (the use of inline); see §15.2.2. Sadly, I have seen worse.In most cases, we can achieve versioning by less intrusive means. The only example I can thinkof that is completely impossible to do by other means is the specialization of a template explicitlyusing the namespace name (e.g., Popular::C<T∗>). However, in many important cases ‘‘in mostcases’’ isn’t good enough. Also, a solution based on a combination of other techniques is less obviously completely right.14.4.7 Nested NamespacesOne obvious use of namespaces is to wrap a complete set of declarations and definitions in a separate namespace:namespace X {// ...

all my declarations ...}The list of declarations will, in general, contain namespaces. Thus, nested namespaces are allowed.This is allowed for practical reasons, as well as for the simple reason that constructs ought to nestunless there is a strong reason for them not to. For example:void h();namespace X {void g();// ...namespace Y {void f();void ff();// ...}}The usual scope and qualification rules apply:void X::Y::ff(){f(); g(); h();}Section 14.4.7void X::g(){f();Y::f();}void h(){f();Y::f();X::f();X::Y::f();}Nested Namespaces415// error: no f() in X// OK// error: no global f()// error: no global Y// error: no f() in X// OKFor examples of nested namespaces in the standard library, see(§35.5.3).chrono(§35.2) andrel_ops14.4.8 Unnamed NamespacesIt is sometimes useful to wrap a set of declarations in a namespace simply to protect against thepossibility of name clashes. That is, the aim is to preserve locality of code rather than to present aninterface to users.

For example:#include "header.h"namespace Mine {int a;void f() { /* ... */ }int g() { /* ... */ }}Since we don’t want the name Mine to be known outside a local context, it simply becomes a botherto invent a redundant global name that might accidentally clash with someone else’s names. In thatcase, we can simply leave the namespace without a name:#include "header.h"namespace {int a;void f() { /* ...

*/ }int g() { /* ... */ }}Clearly, there has to be some way of accessing members of an unnamed namespace from outsidethe unnamed namespace. Consequently, an unnamed namespace has an implied using-directive.The previous declaration is equivalent tonamespace $$$ {int a;void f() { /* ... */ }int g() { /* ... */ }}using namespace $$$;416NamespacesChapter 14where $$$ is some name unique to the scope in which the namespace is defined. In particular,unnamed namespaces in different translation units are different.

As desired, there is no way ofnaming a member of an unnamed namespace from another translation unit.14.4.9 C HeadersConsider the canonical first C program:#include <stdio.h>int main(){printf("Hello, world!\n");}Breaking this program wouldn’t be a good idea. Making standard libraries special cases isn’t agood idea either. Consequently, the language rules for namespaces are designed to make it relatively easy to take a program written without namespaces and turn it into a more explicitly structured one using namespaces. In fact, the calculator program (§10.2) is an example of this.One way to provide the standard C I/O facilities in a namespace would be to place the declarations from the C header stdio.h in a namespace std:// cstdio:namespace std {int printf(const char∗ ... );// ...}Given this <cstdio>, we could provide backward compatibility by adding a using-directive:// stdio.h:#include<cstdio>using namespace std;This <stdio.h> makes the Hello, world! program compile.

Unfortunately, the using-directive makesevery name from namespace std accessible in the global namespace. For example:#include<vector>vector v1;#include<stdio.h>vector v2;// carefully avoids polluting the global namespace// error: no ‘‘vector’’ in global scope// contains a ‘‘using namespace std;’’// oops: this now worksSo the standard requires that <stdio.h> place only names from <cstdio> in the global scope.

Характеристики

Тип файла
PDF-файл
Размер
18,76 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6417
Авторов
на СтудИзбе
307
Средний доход
с одного платного файла
Обучение Подробнее