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

• Declare overriding functions override.

• Member function reference qualifiers make it possible to treat lvalue and rvalue objects ( *this) differently.

Item 13: Prefer const_iterators to iterators.

const_iterators are the STL equivalent of pointers-to- const. They point to values that may not be modified. The standard practice of using constwhenever possible dictates that you should use const_iterators any time you need an iterator, yet have no need to modify what the iterator points to.

That's as true for C++98 as for C++11, but in C++98, const_iterators had only halfhearted support. It wasn't that easy to create them, and once you had one, the ways you could use it were limited. For example, suppose you want to search a std::vectorfor the first occurrence of 1983 (the year “C++” replaced “C with Classes” as the name of the programming language), then insert the value 1998 (the year the first ISO C++ Standard was adopted) at that location. If there's no 1983 in the vector, the insertion should go at the end of the vector. Using iterators in C++98, that was easy:

std::vector values;

std::vector::iterator it =

std::find(values.begin(),values.end(), 1983);

values.insert(it, 1998);

But iterators aren't really the proper choice here, because this code never modifies what an iteratorpoints to. Revising the code to use const_iterators should be trivial, but in C++98, it was anything but. Here's one approach that's conceptually sound, though still not correct:

typedef std::vector::iterator IterT; // type-

typedef std::vector::const_iterator ConstIterT; // defs

std::vector values;

ConstIterT ci =

std::find( static_cast(values.begin() ), // cast

static_cast(values.end() ), // cast

1983);

values.insert( static_cast(ci), 1998); // may not

// compile; see

// below

The typedefs aren't required, of course, but they make the casts in the code easier to write. (If you're wondering why I'm showing typedefs instead of following the advice of Item 9to use alias declarations, it's because this example shows C++98 code, and alias declarations are a feature new to C++11.)

The casts in the call to std::findare present because valuesis a non- constcontainer and in C++98, there was no simple way to get a const_iteratorfrom a non- constcontainer. The casts aren't strictly necessary, because it was possible to get const_iterators in other ways (e.g., you could bind valuesto a reference-to- constvariable, then use that variable in place of valuesin your code), but one way or another, the process of getting const_iterators to elements of a non- constcontainer involved some amount of contorting.

Once you had the const_iterators, matters often got worse, because in C++98, locations for insertions (and erasures) could be specified only by iterators. const_iterators weren't acceptable. That's why, in the code above, I cast the const_iterator(that I was so careful to get from std::find) into an iterator: passing a const_iteratorto insertwouldn't compile.

To be honest, the code I've shown might not compile, either, because there's no portable conversion from a const_iteratorto an iterator, not even with a static_cast. Even the semantic sledgehammer known as reinterpret_castcan't do the job. (That's not a C++98 restriction. It's true in C++11, too. const_iterators simply don't convert to iterators, no matter how much it might seem like they should.) There are some portable ways to generate i terators that point where const_iterators do, but they're not obvious, not universally applicable, and not worth discussing in this book. Besides, I hope that by now my point is clear: const_iterators were so much trouble in C++98, they were rarely worth the bother. At the end of the day, developers don't use constwhenever possible , they use it whenever practical , and in C++98, const_iterators just weren't very practical.

All that changed in C++11. Now const_iterators are both easy to get and easy to use. The container member functions cbeginand cendproduce const_iterators, even for non- constcontainers, and STL member functions that use iterators to identify positions (e.g., insert and erase) actually use const_iterators. Revising the original C++98 code that uses iterators to use const_iterators in C++11 is truly trivial:

std::vector values; // as before

autoit = // use cbegin

std::find(values. cbegin(),values. cend(), 1983); // and cend

values.insert(it, 1998);

Now that's code using const_iterators that's practical!

About the only situation in which C++11's support for const_iterators comes up a bit short is when you want to write maximally generic library code. Such code takes into account that some containers and container-like data structures offer beginand end(plus cbegin, cend, rbegin, etc.) as non-member functions, rather than members. This is the case for built-in arrays, for example, and it's also the case for some third-party libraries with interfaces consisting only of free functions. Maximally generic code thus uses non-member functions rather than assuming the existence of member versions.

For example, we could generalize the code we've been working with into a findAndInserttemplate as follows:

template

void findAndInsert(C& container, // in container, find

const V& targetVal, // first occurrence

const V& insertVal) // of targetVal, then

{ // insert insertVal

using std::cbegin; // there

using std::cend;

auto it = std::find( cbegin(container), // non-member cbegin

cend(container), // non-member cend

targetVal);

container.insert(it, insertVal);

}

This works fine in C++14, but, sadly, not in C++11. Through an oversight during standardization, C++11 added the non-member functions beginand end, but it failed to add cbegin, cend, rbegin, rend, crbegin, and crend. C++14 rectifies that oversight.

If you're using C++11, you want to write maximally generic code, and none of the libraries you're using provides the missing templates for non-member cbeginand friends, you can throw your own implementations together with ease. For example, here's an implementation of non-member cbegin:

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

Интервал:

Закладка:

Сделать

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

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


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

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

x