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

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

Интервал:

Закладка:

Сделать
Things to Remember

std::moveperforms an unconditional cast to an rvalue. In and of itself, it doesn't move anything.

std::forwardcasts its argument to an rvalue only if that argument is bound to an rvalue.

• Neither std::movenor std::forwarddo anything at runtime.

Item 24: Distinguish universal references from rvalue references.

It's been said that the truth shall set you free, but under the right circumstances, a well-chosen lie can be equally liberating. This Item is such a lie. Because we're dealing with software, however, let's eschew the word “lie” and instead say that this Item comprises an “abstraction.”

To declare an rvalue reference to some type T, you write T&&. It thus seems reasonable to assume that if you see “ T&&” in source code, you're looking at an rvalue reference. Alas, it's not quite that simple:

void f(Widget &&param); // rvalue reference

Widget &&var1 = Widget(); // rvalue reference

auto &&var2 = var1; // not rvalue reference

template

void f(std::vector &&param); // rvalue reference

template

void f(T &&param); // not rvalue reference

In fact, “ T&&” has two different meanings. One is rvalue reference, of course. Such references behave exactly the way you expect: they bind only to rvalues, and their primary raison d'être is to identify objects that may be moved from.

The other meaning for “ T&&” is either rvalue reference or lvalue reference. Such references look like rvalue references in the source code (i.e., “ T&&”), but they can behave as if they were lvalue references (i.e., “ T&”). Their dual nature permits them to bind to rvalues (like rvalue references) as well as lvalues (like lvalue references). Furthermore, they can bind to constor non- constobjects, to volatileor non- volatileobjects, even to objects that are both constand volatile. They can bind to virtually anything . Such unprecedentedly flexible references deserve a name of their own. I call them universal references . [11] Item 25 explains that universal references should almost always have std::forward applied to them, and as this book goes to press, some members of the C++ community have started referring to universal references as forwarding references .

Universal references arise in two contexts. The most common is function template parameters, such as this example from the sample code above:

template

void f( T&&param); // param is a universal reference

The second context is autodeclarations, including this one from the sample code above:

auto &&var2 = var1; // var2 is a universal reference

What these contexts have in common is the presence of type deduction . In the template f, the type of paramis being deduced, and in the declaration for var2, var2's type is being deduced. Compare that with the following examples (also from the sample code above), where type deduction is missing. If you see “ T&&” without type deduction, you're looking at an rvalue reference:

void f(Widget &&param); // no type deduction;

// param is an rvalue reference

Widget &&var1 = Widget(); // no type deduction;

// var1 is an rvalue reference

Because universal references are references, they must be initialized. The initializer for a universal reference determines whether it represents an rvalue reference or an lvalue reference. If the initializer is an rvalue, the universal reference corresponds to an rvalue reference. If the initializer is an lvalue, the universal reference corresponds to an lvalue reference. For universal references that are function parameters, the initializer is provided at the call site:

template

void f(T&& param); // param is a universal reference

Widget w;

f( w); // lvalue passed to f; param's type is

// Widget& (i.e., an lvalue reference)

f( std::move(w)); // rvalue passed to f; param's type is

// Widget&& (i.e., an rvalue reference)

For a reference to be universal, type deduction is necessary, but it's not sufficient. The form of the reference declaration must also be correct, and that form is quite constrained. It must be precisely “ T&&”. Look again at this example from the sample code we saw earlier:

template

void f( std::vector&&param); // param is an rvalue reference

When fis invoked, the type Twill be deduced (unless the caller explicitly specifies it, an edge case we'll not concern ourselves with). But the form of param's type declaration isn't “ T&&”, it's “ std::vector&&”. That rules out the possibility that paramis a universal reference. paramis therefore an rvalue reference, something that your compilers will be happy to confirm for you if you try to pass an lvalue to f:

std::vector v;

f(v); // error! can't bind lvalue to

// rvalue reference

Even the simple presence of a constqualifier is enough to disqualify a reference from being universal:

template

void f( constT&& param); // param is an rvalue reference

If you're in a template and you see a function parameter of type “ T&&”, you might think you can assume that it's a universal reference. You can't. That's because being in a template doesn't guarantee the presence of type deduction. Consider this push_backmember function in std::vector:

template> // from C++

class vector { // Standards

public:

void push_back( T&&x);

};

push_back's parameter certainly has the right form for a universal reference, but there's no type deduction in this case. That's because push_backcan't exist without a particular vectorinstantiation for it to be part of, and the type of that instantiation fully determines the declaration for push_back. That is, saying

std::vector v;

causes the std::vector template to be instantiated as follows:

class vector> {

public:

void push_back( Widget&&x); // rvalue reference

};

Now you can see clearly that push_backemploys no type deduction. This push_backfor vector(there are two — the function is overloaded) always declares a parameter of type rvalue-reference-to- T.

In contrast, the conceptually similar emplace_backmember function in std::vector does employ type deduction:

template> // still from

class vector { // C++

public: // Standards

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

Интервал:

Закладка:

Сделать

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

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


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

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

x