0% found this document useful (0 votes)
51 views75 pages

Scott Meyers C++ Modern Effective2

The document discusses different types of template, auto, and decltype type deduction in C++. It explains the three cases of template type deduction when the parameter type is a reference/pointer, universal reference, or neither. It also discusses auto type deduction and how decltype can deduce the exact type of an expression.

Uploaded by

Abdelrhman Tarek
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
51 views75 pages

Scott Meyers C++ Modern Effective2

The document discusses different types of template, auto, and decltype type deduction in C++. It explains the three cases of template type deduction when the parameter type is a reference/pointer, universal reference, or neither. It also discusses auto type deduction and how decltype can deduce the exact type of an expression.

Uploaded by

Abdelrhman Tarek
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 75

C1 I1 Understand template type deduction.

Thursday, April 4, 2024 5:06 AM

3 types of type deduction : 1-template 2-auto 3-decltype

ParamType here is ( T + (& or && .) )

During compilation, compilers use expr to deduce two types: one for T and one for
ParamType.

These types are frequently different, because ParamType often contains


adornments

The three types of template deduction :

ParamType is a pointer or reference type, but not a universal reference.


ParamType is a universal reference.
ParamType is neither a pointer nor a reference.

(1) ParamType is a Reference or Pointer, but not a Universal Reference

Steps : ignore ref => match "expr" with "paramType" to get "T"

Book items Page 1


NOTE : T is only a type(int , double ) + (const or non const ) e.g(const int or int)

(2) ParamType is a Universal Reference

|-> 1 - if "expr" is lvalue so T and paramtypes dudced to be lvalue ref


Steps: |
|->2- else case 1 will be dominat

Book items Page 2


(3) ParamType is Neither a Pointer nor a Reference

Steps : ignore ref => ignore constant

Book items Page 3


Book items Page 4
Book items Page 5
C1 I2 Understand auto type deduction.
Thursday, April 4, 2024 7:43 AM

Auto is like template deduction but only 1 exception case

That s true, but it doesn t matter. There s a direct mapping between template type
deduction and auto type deduction. There is literally an algorithmic transformation
from one to the other.

Book items Page 6


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

The exception is "uniform initializer"

Note : we cant have different types in initializer list

Book items Page 7


Book items Page 8
C1 I3 Understand decltype
Friday, April 5, 2024 8:06 AM

WHAT IS THE USAGE OF "decltype(auto)" It deduced to exact type of a expression , its useful in generic code

Auto -> like template type deduction decltype(auto) -> like expression is

============================================================================================================
In C++11, perhaps the primary use for decltype is declaring function templates
where the function s return type depends on its parameter types. For example, suppose
we d like to write a function that takes a container that supports indexing via
square brackets (i.e., the use of [] ) plus an index, then authenticates the user before
returning the result of the indexing operation. The return type of the function should
be the same as the type returned by the indexing operation.

operator[] on a container of objects of type T typically returns a T&. This is the case
for std::deque, for example, and it s almost always the case for std::vector. For
std::vector<bool>, however, operator[] does not return a bool&. Instead, it
returns a brand new object. The whys and hows of this situation are explored in

El 5olasa --> el [] fe el vector 3latol byrg3 ref msh el kema nfsha fa Lw T byrg3 T& laken el bool msh byrg3 &bool fa 3lshan kda m7tagen el
Decltype(auto) 3lshan mnsh5lsh dm8na be hyrg3 eh

Book items Page 9


Book items Page 10
C2 I5 Prefer auto to explicit type declarations.
Friday, April 5, 2024 10:32 AM

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.

auto variables must be initialized, are generally immune to type mismatches


that can lead to portability or efficiency problems, can ease the process of
refactoring, and typically require less typing than variables with explicitly
specified types.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Book items Page 11


Book items Page 12
Book items Page 13
C3 i7 Distinguish between () and {} when creating objects
Saturday, April 6, 2024 6:54 AM

Braced initialzation ( uniform initialization) EL 5OLASA ENHA CONSTANT TNF3 FE KOL EL CASES

1-in vector initialization

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

2- Non-static member data

3- uncopyable objects (e.g., std::atomics)

4- Prohibits "Narrowing conversions"


Narrowing conversions occur when you attempt to convert a value of a larger data type into a value of a smaller or more restr ictive data type,
potentially losing information in the process.

From <https://chat.openai.com/c/a5b3675f-9376-45ef-96d1-5bf553cd543b>

Book items Page 14


5- Most vexing parse

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DrawBacks !!

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

Book items Page 15


+++++++++++ SOME UNUSUAL CASES

Book items Page 16


Book items Page 17
Book items Page 18
C3 I8 Prefer nullptr to 0 and NULL
Saturday, April 6, 2024 8:03 AM

0 is an int, not a pointer.

Practically speaking, the same is true of NULL. There is some uncertainty in the details
in NULL s case, because implementations are allowed to give NULL an integral type
other than int (e.g., long)

The uncertainty regarding the behavior of f(NULL) is a reflection of the leeway granted
to implementations regarding the type of NULL. If NULL is defined to be, say, 0L
(i.e., 0 as a long), the call is ambiguous, because conversion from long to int, long
to bool, and 0L to void* are considered equally good

nullptr s advantage is that it doesn t have an integral type it doesn t


have a pointer type, either, but you can think of it as a pointer of all types. nullptr s
actual type is std::nullptr_t

The type std::nullptr_t


implicitly converts to all raw pointer types, and that s what makes nullptr act as if it
were a pointer of all types.

f(nullptr); // calls f(void*) overload

Using nullptr instead of 0 or NULL thus avoids overload resolution surprises

Book items Page 19


Book items Page 20
Book items Page 21
Online C++
Compiler

EL 5OLASA EL KLAM DA BY7SL FEL TEMPLATES BS 3LSHAN BY7SL TYPE DUDECTION FA EL TEMPLATE BY7WLA LE INT AW LONG AW AY KAN
LAKEN FEL FUNCTION EL 3ADY YNF3 ABASY 0 AW NULL LE FUNCTION BTA5OD SMART POINTER

Book items Page 22


Book items Page 23
OUPUT

Book items Page 24


C3 i9 Prefer alias declarations to typedefs
Saturday, April 6, 2024 8:47 AM

El 5olasa typedefs mynf3sh m3 el template

Book items Page 25


C3 I10 prefer scoped enums to unscoped ones
Monday, April 8, 2024 7:07 AM

El visibilty bta3 el var byba2 limits ll curly brackets

Laken el klam da msh s7 fel enum 3l 3ady el visibilty byba2 local ll mkan el m3mol feh el enum

El klam da msh mwgod fe case el scoped enums

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feh 3eb tany fel enum el 3adya hwa ano byt7wl l integrals type

Book items Page 26


Book items Page 27
C3 I11 Prefer deleted functions to private undefined ones
Monday, April 8, 2024 7:13 AM

The C++98 approach to preventing use of these functions is to declare them private and not define them

Private : 3lshan mybanosh bra el class


Not Defined : da lw 3lshan feh friend class aw function tany gwa el class

The difference between deleting these functions and declaring them private may
seem more a matter of fashion than anything else, but there s greater substance here
than you might think. Deleted functions may not be used in any way, so even code
that s in member and friend functions will fail to compile if it tries to copy
basic_ios objects.

El deleted byba2 gwa el public section msh el private Leh ?

3lshan el code bycheck el accessibility el awel abl el delted

============================================================================
An important advantage of deleted functions is that any function may be deleted,
while only member functions may be private.

Book items Page 28


Book items Page 29
Book items Page 30
C3 I12 Declare overriding functions override
Monday, April 8, 2024 7:35 AM

For overriding to occur, several requirements must be met:

The base class function must be virtual.


The base and derived function names must be identical (except in the case of
destructors).
The parameter types of the base and derived functions must be identical.
The constness of the base and derived functions must be identical.
The return types and exception specifications of the base and derived functions
must be compatible.

Book items Page 31


Book items Page 32
If u use override then it wont compile so its better

Book items Page 33


Book items Page 34
C3 I14 Declare Functions noexcept if they wont emit exceptions
Sunday, April 14, 2024 5:31 PM

Noexcept internally

Before noexcept (we called copycotr at every expand in capacity) After noexcept

Book items Page 35


C3 I15 Use constexpr whenever possible
Monday, April 15, 2024 11:59 PM

constexpr is a feature added in C++ 11. The main idea is a performance improvement of programs by doing computations at compile
time rather than run time

Book items Page 36


Book items Page 37
C3 I17 Understand special member function generation
Tuesday, April 16, 2024 12:44 AM

C++98 has four such functions: the default constructor, the


destructor, the copy constructor, and the copy assignment operator. There s fine
print, of course. These functions are generated only if they re needed

default constructoris generated only if the class declares no constructors at all

Generated special member functions are


implicitly public and inline, and they re nonvirtual unless the function in question
is a destructor in a derived class inheriting from a base class with a virtual destructor.
In that case, the compiler-generated destructor for the derived class is also virtual.

The move operations are generated only if they re needed, and if


they are generated, they perform memberwise moves

The two copy operations are independent :


So if you declare a copy constructor, but no copy assignment
operator, then write code that requires copy assignment, compilers will generate
the copy assignment operator for you. Similarly, if you declare a copy assignment
operator, but no copy constructor, yet your code requires copy construction, compilers
will generate the copy constructor for you

The two move operations are not independent:


If you declare either, that prevents compilers from generating the other

move operations won t be generated for any class that explicitly


declares a copy operation.

The justification is that declaring a copy operation (con struction or assignment) indicates that the normal approach to copying an
object(memberwise copy) isn t appropriate for the class, and compilers figure that if memberwise copy isn t appropriate for the
copy operations, memberwise move probably isn t appropriate for the move operations.

This goes in the other direction, too. Declaring a move operation (construction or
assignment) in a class causes compilers to disable the copy operations

A consequence of the Rule of Three is that the presence of a user-declared destructor


indicates that simple memberwise copy is unlikely to be appropriate for the copying
operations in the class. That, in turn, suggests that if a class declares a destructor, the
copy operations probably shouldn t be automatically generated, because they
wouldn t do the right thing

So move operations are generated for classes (when needed) only if these three things
are true:
No copy operations are declared in the class.
No move operations are declared in the class.

Book items Page 38


No move operations are declared in the class.
No destructor is declared in the class.

Book items Page 39


Book items Page 40
C4 I18 use std::unique_ptr for exclusive-ownership resource
management
Wednesday, April 17, 2024 5:25 PM

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

by default, std::unique_ptrs are the same size as raw pointers

std::unique_ptr embodies exclusive ownership semantics. A non-null std::unique_ptr always owns what it points to.

Moving a std::unique_ptr transfersownership from the source pointer to the destination pointer. (The source pointer is set to null.) Copying a
std::unique_ptr isn t allowed, move-only type

By default, resource destruction is accomplished by applying delete to the raw pointer inside the std::unique_ptr.

during construction, std::unique_ptr objects can be configured to use custom deleters

All custom deletion functions accept a raw pointer to the object to be destroyed

std::unique_ptr comes in two forms, one for individual objects (std::


unique_ptr<T>) and one for arrays (std::unique_ptr<T[]>). As a result, there s
never any ambiguity about what kind of entity a std::unique_ptr points to

Book items Page 41


Book items Page 42
Book items Page 43
Book items Page 44
C4 I19 Use std::shared_ptr for shared_ownership resource managment
Thursday, April 18, 2024 9:08 AM

A std::shared_ptr can tell whether it s the last one pointing to a resource by consulting the resource s reference count, a value associated with the resource that keeps
track of how many std::shared_ptrs point to it

std::shared_ptr constructors increment this count ,std::shared_ptr destructors decrement it, and copy assignment operators do both

Book items Page 45


Book items Page 46
The comment about this being wrong says it all or at least most of it. (The part
that s wrong is the passing of this, not the use of emplace_back. If you re not familiar
with emplace_back, see Item 42.) This code will compile, but it s passing a raw
pointer (this) to a container of std::shared_ptrs. The std::shared_ptr thus
constructed will create a new control block for the pointed-to Widget (*this). That

Book items Page 47


Book items Page 48
Book items Page 49
C4 I20 Use std::weak_ptr for std::shared_ptr like pointers that can
dangle
Thursday, April 18, 2024 5:40 PM

a pointer like std::shared_ptr that doesn t affect an object s reference count.

std::weak_ptrs are typically created from


std::shared_ptrs. They point to the same place as the std::shared_ptrs initializing
them, but they don t affect the reference count of the object they point to

Book items Page 50


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Cyclic dependency

The cyclic dependency problem with std::shared_ptr occurs when two or more objects hold std::shared_ptr to each other, creati ng a cycle of
ownership. This leads to a situation where the reference counts of these objects never reach zero, preventing them from being destructed
properly. As a result, memory leaks occur despite using std::shared_ptr.
Here's a simple example illustrating the cyclic dependency problem:

Book items Page 51


In this example:
Class A has a member std::shared_ptr<B> and class B has a member std::shared_ptr<A>.
In the main function, two std::shared_ptr objects a and b are created for instances of classes A and B respectively.
Then, a's bPtr and b's aPtr are set to point to each other, creating a cyclic dependency.
When the main function exits, the reference counts of a and b will not reach zero because they are holding each other alive. As a result, the
destructors of A and B will never be called, leading to memory leaks.

One solution to the cyclic dependency problem with std::shared_ptr is to break the cyclic dependency by using std::weak_ptr.
Here's how you can modify the previous example to use std::weak_ptr:

Book items Page 52


In this modified example:
Class A has a member std::shared_ptr<B> and class B has a member std::weak_ptr<A>.
std::weak_ptr is used for the member aWeakPtr in class B to break the cyclic dependency. Unlike std::shared_ptr, std::weak_ptr does not
contribute to the reference count, so it won't prevent the objects from being destructed.
With this change, when the main function exits, the reference count of a will reach zero because b's aWeakPtr does not contribute to the
reference count. This allows the objects to be properly destructed, avoiding memory leaks.

Book items Page 53


Book items Page 54
Book items Page 55
Book items Page 56
C4 I21 Prefere std::make_unique and std::make_shared to direct use of
new
Friday, April 19, 2024 8:03 AM

make_unique just perfect-forwards its parameters to the constructor of the object being created, constructs a std::unique_ptr from the raw pointer new
produces, and returns the std::unique_ptr so created

std::make_unique and std::make_shared are two of the three make functions:functions that take an arbitrary set of arguments, perfect-forward them to the
constructor for a dynamically allocated object, and return a smart pointer to that object.

I ve highlighted the essential difference: the versions using new repeat the type being
created, but the make functions don t. Repeating types runs afoul of a key tenet of
software engineering: code duplication should be avoided. Duplication in source
code increases compilation times, can lead to bloated object code, and generally renders
a code base more difficult to work with. It often evolves into inconsistent code,
and inconsistency in a code base often leads to bugs. Besides, typing something twice
takes more effort than typing it once

Book items Page 57


Book items Page 58
C5 I23 Understand std::move and std::forward
Friday, April 19, 2024 9:09 AM

Rvalue references are the glue that ties these two rather disparate features together.
They re the underlying language mechanism that makes both move semantics and
perfect forwarding possible

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
std::move doesn t move anything. std::forward doesn t forward anything

std::move and std::forward are merely functions (actually function templates)


that perform casts. std::move unconditionally casts its argument to an rvalue, while
std::forward performs this cast only if a particular condition is fulfilled.

1. The function is a template function with a single parameter param of type T&&, which is a universal reference. Universal references are declared using T&& and
can bind to both lvalues and rvalues.
2. Inside the function, remove_reference<T>::type removes any reference from T, ensuring that we get the underlying type without any reference qualifiers.
3. typename remove_reference<T>::type&& then adds an rvalue reference to the type obtained after removing the reference from T. This ensures that the function
returns an rvalue reference, regardless of the type of param.
4. Finally, static_cast is used to cast param to the appropriate reference type, based on the deduction of T. This ensures that the function returns an rvalue

Book items Page 59


There are two lessons to be drawn from this example. First, don t declare objects
const if you want to be able to move from them. Move requests on const objects are
silently transformed into copy operations. Second, std::move not only doesn t
actually move anything, it doesn t even guarantee that the object it s casting will be
eligible to be moved. The only thing you know for sure about the result of applying

Book items Page 60


eligible to be moved. The only thing you know for sure about the result of applying
std::move to an object is that it s an rvalue.

std::forward is a conditional cast: it casts to an rvalue only if its argument was initialized with an rvalue.

You may wonder how std::forward can know whether its argument was initialized
with an rvalue. In the code above, for example, how can std::forward tell whether
param was initialized with an lvalue or an rvalue? The brief answer is that that information
is encoded in logAndProcess s template parameter T. That parameter is
passed to std::forward

More importantly, the use of std::move conveys an unconditional cast to an rvalue,


while the use of std::forward indicates a cast to an rvalue only for references to
which rvalues have been bound. Those are two very different actions. The first one
typically sets up a move, while the second one just passes forwards an object to
another function in a way that retains its original lvalueness or rvalueness. Because
these actions are so different, it s good that we have two different functions (and
function names) to distinguish them.

Book items Page 61


Book items Page 62
C5 I24 Distinguish universal references from the rvalue references
Saturday, April 20, 2024 8:35 AM

Distinguish universal references from rvalue


references.

Book items Page 63


Book items Page 64
C5 I25 Use std::move on rvalue references ,std::forward on universal
references
Saturday, April 20, 2024 9:36 AM

Book items Page 65


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Return Value Optimization (RVO) is an optimization technique used by compilers to avoid unnecessary copying of objects returned from
functions. It optimizes code by constructing the return value directly in the memory location of the caller's destination object, avoiding the
need for temporary objects or additional copy operations.

Without RVO

With RVO

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Book items Page 66


Book items Page 67
Book items Page 68
Book items Page 69
C5 I28 Understand reference collapsing.
Saturday, April 20, 2024 3:53 PM

Book items Page 70


Book items Page 71
Book items Page 72
Book items Page 73
Book items Page 74
Book items Page 75

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy