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

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

Интервал:

Закладка:

Сделать

std::atomic ai1 {0 }; // fine

std::atomic ai2 (0 ); // fine

std::atomic ai3 =0; // error!

It's thus easy to understand why braced initialization is called “uniform.” Of C++'s three ways to designate an initializing expression, only braces can be used everywhere.

A novel feature of braced initialization is that it prohibits implicit narrowing conversions among built-in types. If the value of an expression in a braced initializer isn't guaranteed to be expressible by the type of the object being initialized, the code won't compile:

double x, y, z;

int sum1 {x + y + z }; // error! sum of doubles may

// not be expressible as int

Initialization using parentheses and “ =” doesn't check for narrowing conversions, because that could break too much legacy code:

int sum2 (x + y + z ); // okay (value of expression

// truncated to an int)

int sum3 =x + y + z; // ditto

Another noteworthy characteristic of braced initialization is its immunity to C++'s most vexing parse . A side effect of C++'s rule that anything that can be parsed as a declaration must be interpreted as one, the most vexing parse most frequently afflicts developers when they want to default-construct an object, but inadvertently end up declaring a function instead. The root of the problem is that if you want to call a constructor with an argument, you can do it like this,

Widget w1 (10); // call Widget ctor with argument 10

but if you try to call a Widget constructor with zero arguments using the analogous syntax, you declare a function instead of an object:

Widget w2 (); // most vexing parse! declares a function

// named w2 that returns a Widget!

Functions can't be declared using braces for the parameter list, so default-constructing an object using braces doesn't have this problem:

Widget w3 {}; // calls Widget ctor with no args

There's thus a lot to be said for braced initialization. It's the syntax that can be used in the widest variety of contexts, it prevents implicit narrowing conversions, and it's immune to C++'s most vexing parse. A trifecta of goodness! So why isn't this Item entitled something like “Prefer braced initialization syntax”?

The drawback to braced initialization is the sometimes-surprising behavior that accompanies it. Such behavior grows out of the unusually tangled relationship among braced initializers, std::initializer_lists, and constructor overload resolution. Their interactions can lead to code that seems like it should do one thing, but actually does another. For example, Item 2explains that when an auto-declared variable has a braced initializer, the type deduced is std::initializer_list, even though other ways of declaring a variable with the same initializer would yield a more intuitive type. As a result, the more you like auto, the less enthusiastic you're likely to be about braced initialization.

In constructor calls, parentheses and braces have the same meaning as long as std::initializer_listparameters are not involved:

class Widget {

public:

Widget(int i, bool b); // ctors not declaring

Widget(int i, double d); // std::initializer_list params

};

Widget w1 (10, true ); // calls first ctor

Widget w2 {10, true }; // also calls first ctor

Widget w3 (10, 5.0 ); // calls second ctor

Widget w4 {10, 5.0 }; // also calls second ctor

If, however, one or more constructors declare a parameter of type std::initializer_list, calls using the braced initialization syntax strongly prefer the overloads taking std::initializer_lists. Strongly . If there's any way for compilers to construe a call using a braced initializer to be to a constructor taking a std::initializer_list, compilers will employ that interpretation. If the Widget class above is augmented with a constructor taking a std::initializer_list, for example,

class Widget {

public:

Widget(int i, bool b); // as before

Widget(int i, double d); // as before

Widget(std::initializer_list il);// added

};

Widgets w2and w4will be constructed using the new constructor, even though the type of the std::initializer_listelements ( long double) is, compared to the non- std::initializer_listconstructors, a worse match for both arguments! Look:

Widget w1 (10, true ); // uses parens and, as before,

// calls first ctor

Widget w2 {10, true }; // uses braces, but now calls

// std::initializer_list ctor

// (10 and true convert to long double)

Widget w3 (10, 5.0 ); // uses parens and, as before,

// calls second ctor

Widget w4 {10, 5.0 }; // uses braces, but now calls

// std::initializer_list ctor

// (10 and 5.0 convert to long double)

Even what would normally be copy and move construction can be hijacked by std::initializer_listconstructors:

class Widget {

public:

Widget(int i, bool b); // as before

Widget(int i, double d); // as before

Widget(std::initializer_list il); // as before

operator float() const; // convert

… // to float

};

Widget w5 (w4 ); // uses parens, calls copy ctor

Widget w6 {w4 }; // uses braces, calls

// std::initializer_list ctor

// (w4 converts to float, and float

// converts to long double)

Widget w7 (std::move(w4) ); // uses parens, calls move ctor

Widget w8 {std::move(w4) }; // uses braces, calls

// std::initializer_list ctor

// (for same reason as w6)

Compilers' determination to match braced initializers with constructors taking std::initializer_lists is so strong, it prevails even if the best-match std::initializer_listconstructor can't be called. For example:

class Widget {

public:

Widget(int i, bool b); // as before

Widget(int i, double d); // as before

Widget(std::initializer_list< bool> il); // element type is

// now bool

… // no implicit

}; // conversion funcs

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

Интервал:

Закладка:

Сделать

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

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


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

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

x