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

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

Интервал:

Закладка:

Сделать

names.emplace(std::forward(name));

}

By itself, this function works fine, but were we to introduce the overload taking an intthat's used to look up objects by index, we'd be back in the troubled land of Item 26. The goal of this Item is to avoid that. Rather than adding the overload, we'll reimplement logAndAddto delegate to two other functions, one for integral values and one for everything else. logAndAdditself will accept all argument types, both integral and non-integral.

The two functions doing the real work will be named logAndAddImpl, i.e., we'll use overloading. One of the functions will take a universal reference. So we'll have both overloading and universal references. But each function will also take a second parameter, one that indicates whether the argument being passed is integral. This second parameter is what will prevent us from tumbling into the morass described in Item 26, because we'll arrange it so that the second parameter will be the factor that determines which overload is selected.

Yes, I know, “Blah, blah, blah. Stop talking and show me the code!” No problem. Here's an almost-correct version of the updated logAndAdd:

template

void logAndAdd(T&& name) {

logAndAddImpl(std::forward(name),

std::is_integral()); // not quite correct

}

This function forwards its parameter to logAndAddImpl, but it also passes an argument indicating whether that parameter's type ( T) is integral. At least, that's what it's supposed to do. For integral arguments that are rvalues, it's also what it does. But, as Item 28explains, if an lvalue argument is passed to the universal reference name, the type deduced for T will be an lvalue reference. So if an lvalue of type intis passed to logAndAdd, Twill be deduced to be int&. That's not an integral type, because references aren't integral types. That means that std::is_integralwill be false for any lvalue argument, even if the argument really does represent an integral value.

Recognizing the problem is tantamount to solving it, because the ever-handy Standard C++ Library has a type trait (see Item 9), std::remove_reference, that does both what its name suggests and what we need: remove any reference qualifiers from a type. The proper way to write logAndAdd is therefore:

template

void logAndAdd(T&& name) {

logAndAddImpl(

std::forward(name),

std::is_integral< typename std::remove_reference::type>()

);

}

This does the trick. (In C++14, you can save a few keystrokes by using std::remove_reference_tin place of the highlighted text. For details, see Item 9.)

With that taken care of, we can shift our attention to the function being called, logAndAddImpl. There are two overloads, and the first is applicable only to non-integral types (i.e., to types where std::is_integral::type>is false):

template // non-integral

void logAndAddImpl(T&& name, std::false_type) // argument:

{ // add it to

auto now = std::chrono::system_clock::now(); // global data

log(now, "logAndAdd"); // structure

names.emplace(std::forward(name));

}

This is straightforward code, once you understand the mechanics behind the highlighted parameter. Conceptually, logAndAddpasses a boolean to logAndAddImplindicating whether an integral type was passed to logAndAdd, but trueand falseare runtime values, and we need to use overload resolution — a compile-time phenomenon — to choose the correct logAndAddImploverload. That means we need a type that corresponds to trueand a different type that corresponds to false. This need is common enough that the Standard Library provides what is required under the names std::true_typeand std::false_type. The argument passed to logAndAddImplby logAndAddis an object of a type that inherits from std::true_typeif Tis integral and from std::false_typeif Tis not integral. The net result is that this logAndAddImploverload is a viable candidate for the call in logAndAddonly if Tis not an integral type.

The second overload covers the opposite case: when Tis an integral type. In that event, logAndAddImplsimply finds the name corresponding to the passed-in index and passes that name back to logAndAdd:

std::string nameFromIdx(int idx); // as in Item 26

void logAndAddImpl(int idx, std::true_type) // integral

{ // argument: look

logAndAdd(nameFromIdx(idx)); // up name and

} // call logAndAdd

// with it

By having logAndAddImplfor an index look up the corresponding name and pass it to logAndAdd(from where it will be std::forwarded to the other logAndAddImploverload), we avoid the need to put the logging code in both logAndAddImploverloads.

In this design, the types std::true_typeand std::false_typeare “tags” whose only purpose is to force overload resolution to go the way we want. Notice that we don't even name those parameters. They serve no purpose at runtime, and in fact we hope that compilers will recognize that the tag parameters are unused and will optimize them out of the program's execution image. (Some compilers do, at least some of the time.) The call to the overloaded implementation functions inside logAndAdd“dispatches” the work to the correct overload by causing the proper tag object to be created. Hence the name for this design: tag dispatch . It's a standard building block of template metaprogramming, and the more you look at code inside contemporary C++ libraries, the more often you'll encounter it.

For our purposes, what's important about tag dispatch is less how it works and more how it permits us to combine universal references and overloading without the problems described in Item 26. The dispatching function — logAndAdd— takes an unconstrained universal reference parameter, but this function is not overloaded. The implementation functions — logAndAddImpl— are overloaded, and one takes a universal reference parameter, but resolution of calls to these functions depends not just on the universal reference parameter, but also on the tag parameter, and the tag values are designed so that no more than one overload will be a viable match. As a result, it's the tag that determines which overload gets called. The fact that the universal reference parameter will always generate an exact match for its argument is immaterial.

Constraining templates that take universal references

A keystone of tag dispatch is the existence of a single (unoverloaded) function as the client API. This single function dispatches the work to be done to the implementation functions. Creating an unoverloaded dispatch function is usually easy, but the second problem case Item 26considers, that of a perfect-forwarding constructor for the Personclass (shown on page 178), is an exception. Compilers may generate copy and move constructors themselves, so even if you write only one constructor and use tag dispatch within it, some constructor calls may be handled by compiler-generated functions that bypass the tag dispatch system.

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

Интервал:

Закладка:

Сделать

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

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


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

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

x