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

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

Интервал:

Закладка:

Сделать

The explicitly typed initializer idiom involves declaring a variable with auto, but casting the initialization expression to the type you want auto to deduce. Here's how it can be used to force highPriorityto be a bool, for example:

autohighPriority = static_cast(features(w)[5] );

Here, features(w)[5]continues to return a std::vector::referenceobject, just as it always has, but the cast changes the type of the expression to bool, which autothen deduces as the type for highPriority. At runtime, the std::vector::referenceobject returned from std::vector::operator[]executes the conversion to boolthat it supports, and as part of that conversion, the still-valid pointer to the std::vectorreturned from features is dereferenced. That avoids the undefined behavior we ran into earlier. The index 5 is then applied to the bits pointed to by the pointer, and the boolvalue that emerges is used to initialize highPriority.

For the Matrixexample, the explicitly typed initializer idiom would look like this:

autosum = static_cast(m1 + m2 + m3 + m4 );

Applications of the idiom aren't limited to initializers yielding proxy class types. It can also be useful to emphasize that you are deliberately creating a variable of a type that is different from that generated by the initializing expression. For example, suppose you have a function to calculate some tolerance value:

double calcEpsilon(); // return tolerance value

calcEpsilonclearly returns a double, but suppose you know that for your application, the precision of a floatis adequate, and you care about the difference in size between floats and doubles. You could declare a float variable to store the result of calcEpsilon,

floatep = calcEpsilon(); // impliclitly convert

// double → float

but this hardly announces “I'm deliberately reducing the precision of the value returned by the function.” A declaration using the explicitly typed initializer idiom, however, does:

autoep = static_cast(calcEpsilon() );

Similar reasoning applies if you have a floating-point expression that you are deliberately storing as an integral value. Suppose you need to calculate the index of an element in a container with random access iterators (e.g., a std::vector, std::deque, or std::array), and you're given a doublebetween 0.0and 1.0indicating how far from the beginning of the container the desired element is located. ( 0.5would indicate the middle of the container.) Further suppose that you're confident that the resulting index will fit in an int. If the container is c and the double is d, you could calculate the index this way,

intindex = d * c.size();

but this obscures the fact that you're intentionally converting the doubleon the right to an int. The explicitly typed initializer idiom makes things transparent:

autoindex = static_cast(d * c.size() );

Things to Remember

• “Invisible” proxy types can cause autoto deduce the “wrong” type for an initializing expression.

• The explicitly typed initializer idiom forces autoto deduce the type you want it to have.

Chapter 3

Moving to Modern C++

When it comes to big-name features, C++11 and C++14 have a lot to boast of. auto, smart pointers, move semantics, lambdas, concurrency — each is so important, I devote a chapter to it. It's essential to master those features, but becoming an effective modern C++ programmer requires a series of smaller steps, too. Each step answers specific questions that arise during the journey from C++98 to modern C++. When should you use braces instead of parentheses for object creation? Why are alias declarations better than typedefs? How does constexprdiffer from const? What's the relationship between constmember functions and thread safety? The list goes on and on. And one by one, this chapter provides the answers.

Item 7: Distinguish between ()and {}when creating objects.

Depending on your perspective, syntax choices for object initialization in C++11 embody either an embarrassment of riches or a confusing mess. As a general rule, initialization values may be specified with parentheses, an equals sign, or braces:

int x (0 ); // initializer is in parentheses

int y =0; // initializer follows "="

int z {0 }; // initializer is in braces

In many cases, it's also possible to use an equals sign and braces together:

int z = {0 }; // initializer uses "=" and braces

For the remainder of this Item, I'll generally ignore the equals-sign-plus-braces syntax, because C++ usually treats it the same as the braces-only version.

The “confusing mess” lobby points out that the use of an equals sign for initialization often misleads C++ newbies into thinking that an assignment is taking place, even though it's not. For built-in types like int, the difference is academic, but for user-defined types, it's important to distinguish initialization from assignment, because different function calls are involved:

Widget w1; // call default constructor

Widget w2 = w1; // not an assignment; calls copy ctor

w1 = w2; // an assignment; calls copy operator=

Even with several initialization syntaxes, there were some situations where C++98 had no way to express a desired initialization. For example, it wasn't possible to directly indicate that an STL container should be created holding a particular set of values (e.g., 1, 3, and 5).

To address the confusion of multiple initialization syntaxes, as well as the fact that they don't cover all initialization scenarios, C++11 introduces uniform initialization : a single initialization syntax that can, at least in concept, be used anywhere and express everything. It's based on braces, and for that reason I prefer the term braced initialization . “Uniform initialization” is an idea. “Braced initialization” is a syntactic construct.

Braced initialization lets you express the formerly inexpressible. Using braces, specifying the initial contents of a container is easy:

std::vector v {1, 3, 5 }; // v's initial content is 1, 3, 5

Braces can also be used to specify default initialization values for non-static data members. This capability — new to C++11 — is shared with the “=” initialization syntax, but not with parentheses:

class Widget {

private:

int x {0 }; // fine, x's default value is 0

int y =0; // also fine

int z(0); // error!

};

On the other hand, uncopyable objects (e.g., std::atomics — see Item 40) may be initialized using braces or parentheses, but not using “=”:

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

Интервал:

Закладка:

Сделать

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

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


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

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

x