Scott Meyers - Effective Modern C++

Здесь есть возможность читать онлайн «Scott Meyers - Effective Modern C++» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: Sebastopol, Год выпуска: 2014, ISBN: 2014, Издательство: O’Reilly, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Effective Modern C++: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Effective Modern C++»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Coming to grips with C++11 and C++14 is more than a matter of familiarizing yourself with the features they introduce (e.g., auto type declarations, move semantics, lambda expressions, and concurrency support). The challenge is learning to use those features
— so that your software is correct, efficient, maintainable, and portable. That's where this practical book comes in. It describes how to write truly great software using C++11 and C++14 — i.e., using
C++.
Topics include:
■ The pros and cons of braced initialization,
specifications, perfect forwarding, and smart pointer make functions
■ The relationships among
,
, rvalue references, and universal references
■ Techniques for writing clear, correct,
lambda expressions
■ How
differs from
, how each should be used, and how they relate to C++'s concurrency API
■ How best practices in “old” C++ programming (i.e., C++98) require revision for software development in modern C++
Effective Modern C++ For more than 20 years,
'
books (
,
, and
) have set the bar for C++ programming guidance. His clear, engaging explanations of complex technical material have earned him a worldwide following, keeping him in demand as a trainer, consultant, and conference presenter. He has a Ph.D. in Computer Science from Brown University.
“After I learned the C++ basics, I then learned how to use C++ in production code from Meyers' series of Effective C++ books. Effective Modern C++ is the most important how-to book for advice on key guidelines, styles, and idioms to use modern C++ effectively and well. Don't own it yet? Buy this one. Now.”
Herb Sutter
Chair of ISO C++ Standards Committee and C++ Software Architect at Microsoft

Effective Modern C++ — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Effective Modern C++», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

• C++14 offers alias templates for all the C++11 type traits transformations.

Item 10: Prefer scoped enums to unscoped enums.

As a general rule, declaring a name inside curly braces limits the visibility of that name to the scope defined by the braces. Not so for the enumerators declared in C++98-style enums. The names of such enumerators belong to the scope containing the enum, and that means that nothing else in that scope may have the same name:

enum Color { black, white, red}; // black, white, red are

// in same scope as Color

auto white= false; // error! white already

// declared in this scope

The fact that these enumerator names leak into the scope containing their enumdefinition gives rise to the official term for this kind of enum: unscoped . Their new C++11 counterparts, scoped enum s , don't leak names in this way:

enum classColor { black, white, red }; // black, white, red

// are scoped to Color

auto white= false; // fine, no other

// "white" in scope

Color c = white; // error! no enumerator named

// "white" is in this scope

Color c = Color::white; // fine

auto c = Color::white; // also fine (and in accord

// with Item 5's advice)

Because scoped enums are declared via “ enum class”, they're sometimes referred to as enum classes .

The reduction in namespace pollution offered by scoped enums is reason enough to prefer them over their unscoped siblings, but scoped enums have a second compelling advantage: their enumerators are much more strongly typed. Enumerators for unscoped enums implicitly convert to integral types (and, from there, to floating-point types). Semantic travesties such as the following are therefore completely valid:

enum Color { black, white, red }; // unscoped enum

std::vector // func. returning

primeFactors(std::size_t x); // prime factors of x

Color c = red;

if (c < 14.5) { // compare Color to double (!)

auto factors = // compute prime factors

primeFactors(c); // of a Color (!)

}

Throw a simple “ class” after “ enum”, however, thus transforming an unscoped enuminto a scoped one, and it's a very different story. There are no implicit conversions from enumerators in a scoped enumto any other type:

enum classColor { black, white, red }; // enum is now scoped

Color c = Color::red; // as before, but

… // with scope qualifier

if (c < 14.5) { // error! can't compare

// Color and double

auto factors = // error! can't pass Color to

primeFactors(c); // function expecting std::size_t

}

If you honestly want to perform a conversion from Colorto a different type, do what you always do to twist the type system to your wanton desires — use a cast:

if ( static_cast(c )< 14.5) { // odd code, but

// it's valid

auto factors = // suspect, but

primeFactors( static_cast(c )); // it compiles

}

It may seem that scoped enums have a third advantage over unscoped enums, because scoped enums may be forward-declared, i.e., their names may be declared without specifying their enumerators:

enum Color; // error!

enum class Color; // fine

This is misleading. In C++11, unscoped enums may also be forward-declared, but only after a bit of additional work. The work grows out of the fact that every enumin C++ has an integral underlying type that is determined by compilers. For an unscoped enumlike Color,

enum Color { black, white, red };

compilers might choose charas the underlying type, because there are only three values to represent. However, some enums have a range of values that is much larger, e.g.:

enum Status { good = 0,

failed = 1,

incomplete = 100,

corrupt = 200,

indeterminate = 0xFFFFFFFF

};

Here the values to be represented range from 0to 0xFFFFFFFF. Except on unusual machines (where a charconsists of at least 32 bits), compilers will have to select an integral type larger than charfor the representation of Statusvalues.

To make efficient use of memory, compilers often want to choose the smallest underlying type for an enumthat's sufficient to represent its range of enumerator values. In some cases, compilers will optimize for speed instead of size, and in that case, they may not choose the smallest permissible underlying type, but they certainly want to be able to optimize for size. To make that possible, C++98 supports only enumdefinitions (where all enumerators are listed); enumdeclarations are not allowed. That makes it possible for compilers to select an underlying type for each enumprior to the enumbeing used.

But the inability to forward-declare enums has drawbacks. The most notable is probably the increase in compilation dependencies. Consider again the Status enum:

enum Status { good = 0,

failed = 1,

incomplete = 100,

corrupt = 200,

indeterminate = 0xFFFFFFFF

};

This is the kind of enumthat's likely to be used throughout a system, hence included in a header file that every part of the system is dependent on. If a new status value is then introduced,

enum Status { good = 0,

failed = 1,

incomplete = 100,

corrupt = 200,

audited = 500,

indeterminate = 0xFFFFFFFF

};

it's likely that the entire system will have to be recompiled, even if only a single subsystem — possibly only a single function! — uses the new enumerator. This is the kind of thing that people hate . And it's the kind of thing that the ability to forward-declare enums in C++11 eliminates. For example, here's a perfectly valid declaration of a scoped enumand a function that takes one as a parameter:

enum class Status; // forward declaration

void continueProcessing(Status s); // use of fwd-declared enum

The header containing these declarations requires no recompilation if Status's definition is revised. Furthermore, if Status is modified (e.g., to add the auditedenumerator), but continueProcessing's behavior is unaffected (e.g., because continueProcessingdoesn't use audited), continueProcessing's implementation need not be recompiled, either.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Effective Modern C++»

Представляем Вашему вниманию похожие книги на «Effective Modern C++» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Effective Modern C++»

Обсуждение, отзывы о книге «Effective Modern C++» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x