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

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

Интервал:

Закладка:

Сделать

T = class Widget const *

param = class Widget const *

Three independent compilers producing the same information suggests that the information is accurate. But look more closely. In the template f, param's declared type is const T&. That being the case, doesn't it seem odd that Tand paramhave the same type? If Twere int, for example, param's type should be const int&— not the same type at all.

Sadly, the results of std::type_info::nameare not reliable. In this case, for example, the type that all three compilers report for param are incorrect. Furthermore, they're essentially required to be incorrect, because the specification for std::type_info::namemandates that the type be treated as if it had been passed to a template function as a by-value parameter. As Item 1explains, that means that if the type is a reference, its reference-ness is ignored, and if the type after reference removal is const(or volatile), its constness (or volatileness) is also ignored. That's why param's type — which is const Widget * const & — is reported as const Widget*. First the type's reference-ness is removed, and then the constness of the resulting pointer is eliminated.

Equally sadly, the type information displayed by IDE editors is also not reliable — or at least not reliably useful. For this same example, one IDE editor I know reports T's type as (I am not making this up):

const

std::_Simple_types

std::allocator >::_Alloc>::value_type>::value_type *

The same IDE editor shows param's type as:

const std::_Simple_types<...>::value_type *const &

That's less intimidating than the type for T, but the “ ...” in the middle is confusing until you realize that it's the IDE editor's way of saying “I'm omitting all that stuff that's part of T's type.” With any luck, your development environment does a better job on code like this.

If you're more inclined to rely on libraries than luck, you'll be pleased to know that where std::type_info::nameand IDEs may fail, the Boost TypeIndex library (often written as Boost.TypeIndex ) is designed to succeed. The library isn't part of Standard C++, but neither are IDEs or templates like TD. Furthermore, the fact that Boost libraries (available at boost.com ) are cross-platform, open source, and available under a license designed to be palatable to even the most paranoid corporate legal team means that code using Boost libraries is nearly as portable as code relying on the Standard Library.

Here's how our function f can produce accurate type information using Boost.TypeIndex:

#include

template

void f(const T& param) {

using std::cout;

using boost::typeindex::type_id_with_cvr;

// show T

cout << "T = "

<< type_id_with_cvr().pretty_name()

<< '\n';

// show param's type

cout << "param = "

<< type_id_with_cvr().pretty_name()

<< '\n';

}

The way this works is that the function template boost::typeindex::type_id_with_cvrtakes a type argument (the type about which we want information) and doesn't remove const, volatile, or reference qualifiers (hence the “ with_cvr” in the template name). The result is a boost::typeindex::type_indexobject, whose pretty_namemember function produces a std::stringcontaining a human-friendly representation of the type.

With this implementation for f, consider again the call that yields incorrect type information for paramwhen typeidis used:

std::vector createVec(); // factory function

const auto vw = createVec(); // init vw w/factory return

if (!vw.empty()) {

f(&vw[0]); // call f

}

Under compilers from GNU and Clang, Boost.TypeIndex produces this (accurate) output:

T = Widget const*

param = Widget const* const&

Results under Microsoft's compiler are essentially the same:

T = class Widget const *

param = class Widget const * const &

Such near-uniformity is nice, but it's important to remember that IDE editors, compiler error messages, and libraries like Boost.TypeIndex are merely tools you can use to help you figure out what types your compilers are deducing. All can be helpful, but at the end of the day, there's no substitute for understanding the type deduction information in Items 13.

Things to Remember

• Deduced types can often be seen using IDE editors, compiler error messages, and the Boost TypeIndex library.

• The results of some tools may be neither helpful nor accurate, so an understanding of C++'s type deduction rules remains essential.

Chapter 2

auto

In concept, autois as simple as simple can be, but it's more subtle than it looks. Using it saves typing, sure, but it also prevents correctness and performance issues that can bedevil manual type declarations. Furthermore, some of auto's type deduction results, while dutifully conforming to the prescribed algorithm, are, from the perspective of a programmer, just wrong. When that's the case, it's important to know how to guide auto to the right answer, because falling back on manual type declarations is an alternative that's often best avoided.

This brief chapter covers all of auto's ins and outs.

Item 5: Prefer autoto explicit type declarations.

Ah, the simple joy of

int x;

Wait. Damn. I forgot to initialize x, so its value is indeterminate. Maybe. It might actually be initialized to zero. Depends on the context. Sigh.

Never mind. Let's move on to the simple joy of declaring a local variable to be initialized by dereferencing an iterator:

template // algorithm to dwim ("do what I mean")

void dwim(It b, It e) // for all elements in range from

{ // b to e

while (b != e) {

typename std::iterator_traits::value_type

currValue = *b;

}

}

Ugh. “ typename std::iterator_traits::value_type” to express the type of the value pointed to by an iterator? Really? I must have blocked out the memory of how much fun that is. Damn. Wait — didn't I already say that?

Okay, simple joy (take three): the delight of declaring a local variable whose type is that of a closure. Oh, right. The type of a closure is known only to the compiler, hence can't be written out. Sigh. Damn.

Damn, damn, damn! Programming in C++ is not the joyous experience it should be!

Well, it didn't used to be. But as of C++11, all these issues go away, courtesy of auto. autovariables have their type deduced from their initializer, so they must be initialized. That means you can wave goodbye to a host of uninitialized variable problems as you speed by on the modern C++ superhighway:

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

Интервал:

Закладка:

Сделать

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

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


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

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

x