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

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

Интервал:

Закладка:

Сделать

Widget&&&& forward( Widget& param) // instantiation of

{ // std::forward when

return static_cast< Widget&&&&>(param); // T is Widget&&

} // (before reference-

// collapsing)

Applying the reference-collapsing rule that an rvalue reference to an rvalue reference becomes a single rvalue reference, this instantiation emerges:

Widget&&forward(Widget& param) // instantiation of

{ // std::forward when

return static_cast< Widget&&>(param); // T is Widget&&

} // (after reference-

// collapsing)

If you compare this instantiation with the one that results when std::forwardis called with Tset to Widget, you'll see that they're identical. That means that instantiating std::forwardwith an rvalue reference type yields the same result as instantiating it with a non-reference type.

That's wonderful news, because decltype(x)yields an rvalue reference type when an rvalue is passed as an argument to our lambda's parameter x. We established above that when an lvalue is passed to our lambda, decltype(x)yields the customary type to pass to std::forward, and now we realize that for rvalues, decltype(x)yields a type to pass to std::forwardthat's not conventional, but that nevertheless yields the same outcome as the conventional type. So for both lvalues and rvalues, passing decltype(x)to std::forwardgives us the result we want. Our perfect-forwarding lambda can therefore be written like this:

auto f =

[](auto&& param) {

return

func(normalize(std::forward< decltype(param)>(param)));

};

From there, it's just a hop, skip, and six dots to a perfect-forwarding lambda that accepts not just a single parameter, but any number of parameters, because C++14 lambdas can also be variadic:

auto f =

[](auto&& ...params) {

return

func(normalize(std::forward(params) ...));

};

Things to Remember

• Use decltypeon auto&&parameters to std::forwardthem.

Item 34: Prefer lambdas to std::bind.

std::bindis the C++11 successor to C++98's std::bind1stand std::bind2nd, but, informally, it's been part of the Standard Library since 2005. That's when the Standardization Committee adopted a document known as TR1, which included bind's specification. (In TR1, bindwas in a different namespace, so it was std::tr1::bind, not std::bind, and a few interface details were different.) This history means that some programmers have a decade or more of experience using std::bind. If you're one of them, you may be reluctant to abandon a tool that's served you well. That's understandable, but in this case, change is good, because in C++11, lambdas are almost always a better choice than std::bind. As of C++14, the case for lambdas isn't just stronger, it's downright ironclad.

This Item assumes that you're familiar with std::bind. If you're not, you'll want to acquire a basic understanding before continuing. Such an understanding is worthwhile in any case, because you never know when you might encounter uses of std::bindin a code base you have to read or maintain.

As in Item 32, I refer to the function objects returned from std::bindas bind objects .

The most important reason to prefer lambdas over std::bindis that lambdas are more readable. Suppose, for example, we have a function to set up an audible alarm:

// typedef for a point in time (see Item 9 for syntax)

using Time = std::chrono::steady_clock::time_point;

// see Item 10 for "enum class"

enum class Sound { Beep, Siren, Whistle };

// typedef for a length of time

using Duration = std::chrono::steady_clock::duration;

// at time t, make sound s for duration d

void setAlarm(Time t, Sound s, Duration d);

Further suppose that at some point in the program, we've determined we'll want an alarm that will go off an hour after it's set and that will stay on for 30 seconds. The alarm sound, however, remains undecided. We can write a lambda that revises setAlarm's interface so that only a sound needs to be specified:

// setSoundL ("L" for "lambda") is a function object allowing a

// sound to be specified for a 30-sec alarm to go off an hour

// after it's set

auto setSoundL =

[](Sound s) {

// make std::chrono components available w/o qualification

using namespace std::chrono;

setAlarm(steady_clock::now() + hours(1),// alarm to go off

s, // in an hour for

seconds(30)); // 30 seconds

};

I've highlighted the call to setAlarminside the lambda. This is a normal-looking function call, and even a reader with little lambda experience can see that the parameter s passed to the lambda is passed as an argument to setAlarm.

We can streamline this code in C++14 by availing ourselves of the standard suffixes for seconds ( s), milliseconds ( ms), hours ( h), etc., that build on C++11's support for user-defined literals. These suffixes are implemented in the std::literalsnamespace, so the above code can be rewritten as follows:

auto setSoundL =

[](Sound s) {

using namespace std::chrono;

using namespace std::literals; // for C++14 suffixes

setAlarm(steady_clock::now() + 1h, // C++14, but

s, // same meaning

30s); // as above

};

Our first attempt to write the corresponding std::bindcall is below. It has an error that we'll fix in a moment, but the correct code is more complicated, and even this simplified version brings out some important issues:

using namespace std::chrono; // as above

using namespace std::literals;

using namespace std::placeholders; // needed for use of "_1"

auto setSoundB = // "B" for "bind"

std::bind(setAlarm,

steady_clock::now() + 1h, // incorrect! see below

_1,

30s);

I'd like to highlight the call to setAlarmhere as I did in the lambda, but there's no call to highlight. Readers of this code simply have to know that calling setSoundBinvokes setAlarmwith the time and duration specified in the call to std::bind. To the uninitiated, the placeholder “ _1” is essentially magic, but even readers in the know have to mentally map from the number in that placeholder to its position in the std::bindparameter list in order to understand that the first argument in a call to setSoundBis passed as the second argument to setAlarm. The type of this argument is not identified in the call to std::bind, so readers have to consult the setAlarmdeclaration to determine what kind of argument to pass to setSoundB.

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

Интервал:

Закладка:

Сделать

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

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


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

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

x