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++», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

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

Интервал:

Закладка:

Сделать

But if compilers need to know the size of an enumbefore it's used, how can C++11's enums get away with forward declarations when C++98's enums can't? The answer is simple: the underlying type for a scoped enumis always known, and for unscoped enums, you can specify it.

By default, the underlying type for scoped enums is int:

enum class Status; // underlying type is int

If the default doesn't suit you, you can override it:

enum class Status : std::uint32_t; // underlying type for

// Status is std::uint32_t

// (from )

Either way, compilers know the size of the enumerators in a scoped enum.

To specify the underlying type for an unscoped enum, you do the same thing as for a scoped enum, and the result may be forward-declared:

enum Color : std::uint8_t; // fwd decl for unscoped enum;

// underlying type is

// std::uint8_t

Underlying type specifications can also go on an enum's definition:

enum class Status : std::uint32_t{ good = 0,

failed = 1,

incomplete = 100,

corrupt = 200,

audited = 500,

indeterminate = 0xFFFFFFFF

};

In view of the fact that scoped enums avoid namespace pollution and aren't susceptible to nonsensical implicit type conversions, it may surprise you to hear that there's at least one situation where unscoped enums may be useful. That's when referring to fields within C++11's std::tuples. For example, suppose we have a tuple holding values for the name, email address, and reputation value for a user at a social networking website:

using UserInfo = // type alias; see Item 9

std::tuple

std::string, // email

std::size_t>; // reputation

Though the comments indicate what each field of the tuple represents, that's probably not very helpful when you encounter code like this in a separate source file:

UserInfo uInfo; // object of tuple type

auto val = std::get<1>(uInfo); // get value of field 1

As a programmer, you have a lot of stuff to keep track of. Should you really be expected to remember that field 1 corresponds to the user's email address? I think not. Using an unscoped enumto associate names with field numbers avoids the need to:

enum UserInfoFields { uiName, uiEmail, uiReputation };

UserInfo uInfo; // as before

auto val = std::get< uiEmail>(uInfo); // ah, get value of

// email field

What makes this work is the implicit conversion from UserInfoFieldsto std::size_t, which is the type that std::getrequires.

The corresponding code with scoped enums is substantially more verbose:

enum classUserInfoFields { uiName, uiEmail, uiReputation };

UserInfo uInfo; // as before

auto val =

std::get< static_cast(UserInfoFields::uiEmail)>

(uInfo);

The verbosity can be reduced by writing a function that takes an enumerator and returns its corresponding std::size_tvalue, but it's a bit tricky. std::getis a template, and the value you provide is a template argument (notice the use of angle brackets, not parentheses), so the function that transforms an enumerator into a std::size_thas to produce its result during compilation . As Item 15explains, that means it must be a constexprfunction.

In fact, it should really be a constexprfunction template, because it should work with any kind of enum. And if we're going to make that generalization, we should generalize the return type, too. Rather than returning std::size_t, we'll return the enum's underlying type. It's available via the std::underlying_typetype trait. (See Item 9for information on type traits.) Finally, we'll declare it noexcept(see Item 14), because we know it will never yield an exception. The result is a function template toUTypethat takes an arbitrary enumerator and can return its value as a compile-time constant:

template

constexpr typename std::underlying_type::type

toUType(E enumerator) noexcept {

return

static_cast

std::underlying_type::type>(enumerator);

}

In C++14, toUTypecan be simplified by replacing typename std::underlying_type::typewith the sleeker std::underlying_type_t(see Item 9):

template // C++14

constexpr std::underlying_type _t

toUType(E enumerator) noexcept {

return static_cast_t>(enumerator);

}

The even-sleeker autoreturn type (see Item 3) is also valid in C++14:

template // C++14

constexpr auto

toUType(E enumerator) noexcept {

return static_cast>(enumerator);

}

Regardless of how it's written, toUTypepermits us to access a field of the tuple like this:

auto val = std::get< toUType(UserInfoFields::uiEmail)>(uInfo);

It's still more to write than use of the unscoped enum, but it also avoids namespace pollution and inadvertent conversions involving enumerators. In many cases, you may decide that typing a few extra characters is a reasonable price to pay for the ability to avoid the pitfalls of an enum technology that dates to a time when the state of the art in digital telecommunications was the 2400-baud modem.

Things to Remember

• C++98-style enums are now known as unscoped enums.

• Enumerators of scoped enums are visible only within the enum. They convert to other types only with a cast.

• Both scoped and unscoped enums support specification of the underlying type. The default underlying type for scoped enums is int. Unscoped enums have no default underlying type.

• Scoped enums may always be forward-declared. Unscoped enums may be forward-declared only if their declaration specifies an underlying type.

Item 11: Prefer deleted functions to private undefined ones.

If you're providing code to other developers, and you want to prevent them from calling a particular function, you generally just don't declare the function. No function declaration, no function to call. Easy, peasy. But sometimes C++ declares functions for you, and if you want to prevent clients from calling those functions, the peasy isn't quite so easy any more.

The situation arises only for the “special member functions,” i.e., the member functions that C++ automatically generates when they're needed. Item 17discusses these functions in detail, but for now, we'll worry only about the copy constructor and the copy assignment operator. This chapter is largely devoted to common practices in C++98 that have been superseded by better practices in C++11, and in C++98, if you want to suppress use of a member function, it's almost always the copy constructor, the assignment operator, or both.

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

Интервал:

Закладка:

Сделать

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

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


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

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

x