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

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

Интервал:

Закладка:

Сделать

Widget w {10, 5.0}; // error! requires narrowing conversions

Here, compilers will ignore the first two constructors (the second of which offers an exact match on both argument types) and try to call the constructor taking a std::initializer_list. Calling that constructor would require converting an int (10)and a double (5.0)to bools. Both conversions would be narrowing ( boolcan't exactly represent either value), and narrowing conversions are prohibited inside braced initializers, so the call is invalid, and the code is rejected.

Only if there's no way to convert the types of the arguments in a braced initializer to the type in a std::initializer_listdo compilers fall back on normal overload resolution. For example, if we replace the std::initializer_listconstructor with one taking a std::initializer_list, the non- std::initializer_listconstructors become candidates again, because there is no way to convert ints and bools to std::strings:

class Widget {

public:

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

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

// std::initializer_list element type is now std::string

Widget(std::initializer_list< std::string> il);

… // no implicit

}; // conversion funcs

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

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

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

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

This brings us near the end of our examination of braced initializers and constructor overloading, but there's an interesting edge case that needs to be addressed. Suppose you use an empty set of braces to construct an object that supports default construction and also supports std::initializer_listconstruction. What do your empty braces mean? If they mean “no arguments,” you get default construction, but if they mean “empty std::initializer_list,” you get construction from a std::initializer_list with no elements.

The rule is that you get default construction. Empty braces mean no arguments, not an empty std::initializer_list:

class Widget {

public:

Widget(); // default ctor

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

// _list ctor

… // no implicit

}; // conversion funcs

Widget w1; // calls default ctor

Widget w2 {}; // also calls default ctor

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

If you want to call a std::initializer_listconstructor with an empty std::initializer_list, you do it by making the empty braces a constructor argument — by putting the empty braces inside the parentheses or braces demarcating what you're passing:

Widget w4( {}); // calls std::initializer_list ctor

// with empty list

Widget w5{ {}}; // ditto

At this point, with seemingly arcane rules about braced initializers, std::initializer_lists, and constructor overloading burbling about in your brain, you may be wondering how much of this information matters in day-to-day programming. More than you might think, because one of the classes directly affected is std::vector. std::vectorhas a non- std::initializer_listconstructor that allows you to specify the initial size of the container and a value each of the initial elements should have, but it also has a constructor taking a std::initializer_listthat permits you to specify the initial values in the container. If you create a std::vectorof a numeric type (e.g., a std::vector) and you pass two arguments to the constructor, whether you enclose those arguments in parentheses or braces makes a tremendous difference:

std::vector v1 (10, 20 ); // use non-std::initializer_list

// ctor : create 10-element

// std::vector, all elements have

// value of 20

std::vector v2 {10, 20 }; // use std::initializer_list ctor :

// create 2-element std::vector,

// element values are 10 and 20

But let's step back from std::vectorand also from the details of parentheses, braces, and constructor overloading resolution rules. There are two primary takeaways from this discussion. First, as a class author, you need to be aware that if your set of overloaded constructors includes one or more functions taking a std::initializer_list, client code using braced initialization may see only the std::initializer_listoverloads. As a result, it's best to design your constructors so that the overload called isn't affected by whether clients use parentheses or braces. In other words, learn from what is now viewed as an error in the design of the std::vectorinterface, and design your classes to avoid it.

An implication is that if you have a class with no std::initializer_listconstructor, and you add one, client code using braced initialization may find that calls that used to resolve to non- std::initializer_listconstructors now resolve to the new function. Of course, this kind of thing can happen any time you add a new function to a set of overloads: calls that used to resolve to one of the old overloads might start calling the new one. The difference with std::initializer_listconstructor overloads is that a std::initializer_listoverload doesn't just compete with other overloads, it overshadows them to the point where the other overloads may hardly be considered. So add such overloads only with great deliberation.

The second lesson is that as a class client, you must choose carefully between parentheses and braces when creating objects. Most developers end up choosing one kind of delimiter as a default, using the other only when they have to. Braces-by-default folks are attracted by their unrivaled breadth of applicability, their prohibition of narrowing conversions, and their immunity to C++'s most vexing parse. Such folks understand that in some cases (e.g., creation of a std::vectorwith a given size and initial element value), parentheses are required. On the other hand, the go- parentheses-go crowd embraces parentheses as their default argument delimiter. They're attracted to its consistency with the C++98 syntactic tradition, its avoidance of the auto-deduced-a- std::initializer_listproblem, and the knowledge that their object creation calls won't be inadvertently waylaid by std::initializer_listconstructors. They concede that sometimes only braces will do (e.g., when creating a container with particular values). There's no consensus that either approach is better than the other, so my advice is to pick one and apply it consistently.

If you're a template author, the tension between parentheses and braces for object creation can be especially frustrating, because, in general, it's not possible to know which should be used. For example, suppose you'd like to create an object of an arbitrary type from an arbitrary number of arguments. A variadic template makes this conceptually straightforward:

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

Интервал:

Закладка:

Сделать

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

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


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

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

x