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

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

Интервал:

Закладка:

Сделать

But perhaps you noticed the weasel words I sprinkled through the preceding discussion. The code “shouldn't” link. References are “usually” treated like pointers. Passing integral static constdata members by reference “generally” requires that they be defined. It's almost like I know something I don't really want to tell you.

That's because I do. According to the Standard, passing MinValsby reference requires that it be defined. But not all implementations enforce this requirement. So, depending on your compilers and linkers, you may find that you can perfect-forward integral static constdata members that haven't been defined. If you do, congratulations, but there is no reason to expect such code to port. To make it portable, simply provide a definition for the integral static constdata member in question. For MinVals, that'd look like this:

const std::size_t Widget::MinVals; // in Widget's .cpp file

Note that the definition doesn't repeat the initializer (28, in the case of MinVals). Don't stress over this detail, however. If you forget and provide the initializer in both places, your compilers will complain, thus reminding you to specify it only once.

Overloaded function names and template names

Suppose our function f (the one we keep wanting to forward arguments to via fwd) can have its behavior customized by passing it a function that does some of its work. Assuming this function takes and returns ints, fcould be declared like this:

void f( int (*pf)(int)); // pf = "processing function"

It's worth noting that fcould also be declared using a simpler non-pointer syntax. Such a declaration would look like this, though it'd have the same meaning as the declaration above:

void f( int pf(int)); // declares same f as above

Either way, now suppose we have an overloaded function, processVal:

int processVal(int value);

int processVal(int value, int priority);

We can pass processValto f,

f(processVal); // fine

but it's something of a surprise that we can. fdemands a pointer to a function as its argument, but processValisn't a function pointer or even a function, it's the name of two different functions. However, compilers know which processValthey need: the one matching f's parameter type. They thus choose the processValtaking one int, and they pass that function's address to f.

What makes this work is that f's declaration lets compilers figure out which version of processValis required. fwd, however, being a function template, doesn't have any information about what type it needs, and that makes it impossible for compilers to determine which overload should be passed:

fwd(processVal); // error! which processVal?

processValalone has no type. Without a type, there can be no type deduction, and without type deduction, we're left with another perfect forwarding failure case.

The same problem arises if we try to use a function template instead of (or in addition to) an overloaded function name. A function template doesn't represent one function, it represents many functions:

template

T workOnVal(T param) // template for processing values

{ … }

fwd(workOnVal); // error! which workOnVal

// instantiation?

The way to get a perfect-forwarding function like fwdto accept an overloaded function name or a template name is to manually specify the overload or instantiation you want to have forwarded. For example, you can create a function pointer of the same type as f's parameter, initialize that pointer with processValor workOnVal(thus causing the proper version of processValto be selected or the proper instantiation of workOnValto be generated), and pass the pointer to fwd:

using ProcessFuncType = // make typedef;

int (*)(int); // see Item 9

ProcessFuncTypeprocessValPtr = processVal; // specify needed

// signature for

// processVal

fwd( processValPtr); // fine

fwd( static_cast(workOnVal)); // also fine

Of course, this requires that you know the type of function pointer that fwdis forwarding to. It's not unreasonable to assume that a perfect-forwarding function will document that. After all, perfect-forwarding functions are designed to accept anything , so if there's no documentation telling you what to pass, how would you know?

Bitfields

The final failure case for perfect forwarding is when a bitfield is used as a function argument. To see what this means in practice, observe that an IPv4 header can be modeled as follows: [13] This assumes that bitfields are laid out lsb (least significant bit) to msb (most significant bit). C++ doesn't guarantee that, but compilers often provide a mechanism that allows programmers to control bitfield layout.

struct IPv4Header {

std::uint32_t version:4,

IHL:4,

DSCP:6,

ECN:2,

totalLength:16;

};

If our long-suffering function f(the perennial target of our forwarding function fwd) is declared to take a std::size_tparameter, calling it with, say, the totalLengthfield of an IPv4Headerobject compiles without fuss:

void f(std::size_t sz); // function to call

IPv4Header h;

f(h.totalLength); // fine

Trying to forward h.totalLengthto fvia fwd, however, is a different story:

fwd(h.totalLength); // error!

The problem is that fwd's parameter is a reference, and h.totalLengthis a non- constbitfield. That may not sound so bad, but the C++ Standard condemns the combination in unusually clear prose: “A non- constreference shall not be bound to a bit-field.” There's an excellent reason for the prohibition. Bitfields may consist of arbitrary parts of machine words (e.g., bits 3-5 of a 32-bit int), but there's no way to directly address such things. I mentioned earlier that references and pointers are the same thing at the hardware level, and just as there's no way to create a pointer to arbitrary bits (C++ dictates that the smallest thing you can point to is a char), there's no way to bind a reference to arbitrary bits, either.

Working around the impossibility of perfect-forwarding a bitfield is easy, once you realize that any function that accepts a bitfield as an argument will receive a copy of the bitfield's value. After all, no function can bind a reference to a bitfield, nor can any function accept pointers to bitfields, because pointers to bitfields don't exist. The only kinds of parameters to which a bitfield can be passed are by-value parameters and, interestingly, references-to- const. In the case of by-value parameters, the called function obviously receives a copy of the value in the bitfield, and it turns out that in the case of a reference-to- constparameter, the Standard requires that the reference actually bind to a copy of the bitfield's value that's stored in an object of some standard integral type (e.g., int). References-to- constdon't bind to bitfields, they bind to “normal” objects into which the values of the bitfields have been copied.

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

Интервал:

Закладка:

Сделать

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

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


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

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

x