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

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

Интервал:

Закладка:

Сделать

MuxGuard g(f3m); // lock mutex for f3

auto result = f3( nullptr); // pass nullptr as null ptr to f3

} // unlock mutex

The failure to use nullptrin the first two calls in this code is sad, but the code works, and that counts for something. However, the repeated pattern in the calling code — lock mutex, call function, unlock mutex — is more than sad. It's disturbing. This kind of source code duplication is one of the things that templates are designed to avoid, so let's templatize the pattern:

template

typename MuxType,

typename PtrType>

auto lockAndCall(FuncType func,

MuxType& mutex,

PtrType ptr) -> decltype(func(ptr)) {

MuxGuard g(mutex);

return func(ptr);

}

If the return type of this function ( auto … -> decltype(func(ptr)) has you scratching your head, do your head a favor and navigate to Item 3, which explains what's going on. There you'll see that in C++14, the return type could be reduced to a simple decltype(auto):

template

typename MuxType,

typename PtrType>

decltype(auto)lockAndCall(FuncType func, // C++14

MuxType& mutex,

PtrType ptr) {

MuxGuard g(mutex);

return func(ptr);

}

Given the lockAndCalltemplate (either version), callers can write code like this:

auto result1 = lockAndCall(f1, f1m, 0); // error!

auto result2 = lockAndCall(f2, f2m, NULL); // error!

auto result3 = lockAndCall(f3, f3m, nullptr); // fine

Well, they can write it, but, as the comments indicate, in two of the three cases, the code won't compile. The problem in the first call is that when 0is passed to lockAndCall, template type deduction kicks in to figure out its type. The type of 0is, was, and always will be int, so that's the type of the parameter ptrinside the instantiation of this call to lockAndCall. Unfortunately, this means that in the call to funcinside lockAndCall, an intis being passed, and that's not compatible with the std::shared_ptrparameter that f1expects. The 0passed in the call to lockAndCallwas intended to represent a null pointer, but what actually got passed was a run-of-the-mill int. Trying to pass this intto f1as a std::shared_ptris a type error. The call to lockAndCallwith 0fails because inside the template, an intis being passed to a function that requires a std::shared_ptr.

The analysis for the call involving NULLis essentially the same. When NULLis passed to lockAndCall, an integral type is deduced for the parameter ptr, and a type error occurs when ptr — an intor int-like type — is passed to f2, which expects to get a std::unique_ptr.

In contrast, the call involving nullptrhas no trouble. When nullptris passed to lockAndCall, the type for ptris deduced to be std::nullptr_t. When ptris passed to f3, there's an implicit conversion from std::nullptr_tto Widget*, because std::nullptr_timplicitly converts to all pointer types.

The fact that template type deduction deduces the “wrong” types for 0and NULL(i.e., their true types, rather than their fallback meaning as a representation for a null pointer) is the most compelling reason to use nullptrinstead of 0or NULLwhen you want to refer to a null pointer. With nullptr, templates pose no special challenge. Combined with the fact that nullptrdoesn't suffer from the overload resolution surprises that 0and NULLare susceptible to, the case is ironclad. When you want to refer to a null pointer, use nullptr, not 0or NULL.

Things to Remember

• Prefer nullptrto 0and NULL.

• Avoid overloading on integral and pointer types.

Item 9: Prefer alias declarations to typedefs.

I'm confident we can agree that using STL containers is a good idea, and I hope that Item 18convinces you that using std::unique_ptris a good idea, but my guess is that neither of us is fond of writing types like “ std::unique_ptr>” more than once. Just thinking about it probably increases the risk of carpal tunnel syndrome.

Avoiding such medical tragedies is easy. Introduce a typedef:

typedef

std::unique_ptr>

UPtrMapSS;

But typedefs are soooo C++98. They work in C++11, sure, but C++11 also offers alias declarations :

using UPtrMapSS =

std::unique_ptr>;

Given that the typedefand the alias declaration do exactly the same thing, it's reasonable to wonder whether there is a solid technical reason for preferring one over the other.

There is, but before I get to it, I want to mention that many people find the alias declaration easier to swallow when dealing with types involving function pointers:

// FP is a synonym for a pointer to a function taking an int and

// a const std::string& and returning nothing

typedefvoid (* FP)(int, const std::string&); // typedef

// same meaning as above

using FP= void (*)(int, const std::string&); // alias

// declaration

Of course, neither form is particularly easy to choke down, and few people spend much time dealing with synonyms for function pointer types, anyway, so this is hardly a compelling reason to choose alias declarations over typedefs.

But a compelling reason does exist: templates. In particular, alias declarations may be templatized (in which case they're called alias templates ), while typedefs cannot. This gives C++11 programmers a straightforward mechanism for expressing things that in C++98 had to be hacked together with typedefs nested inside templatized structs. For example, consider defining a synonym for a linked list that uses a custom allocator, MyAlloc. With an alias template, it's a piece of cake:

template // MyAllocList

using MyAllocList= std::list>; // is synonym for

// std::list

// MyAlloc>

MyAllocList lw; // client code

With a typedef, you pretty much have to create the cake from scratch:

template // MyAllocList::type

struct MyAllocList { // is synonym for

typedefstd::list> type; // std::list

}; // MyAlloc>

MyAllocList::type lw; // client code

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

Интервал:

Закладка:

Сделать

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

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


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

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