Skip to content

hesham-salem/cpp-cheatsheet

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 

Repository files navigation

The goal is to give a concise overview of basic, modern C++ (C++14).

The document is hosted on https://github.com/mortennobel/cpp-cheatsheet. Any comments and feedback are appreciated.

Preprocessor

                         
#include  <stdio.h>         // Insert standard header file
#include "myfile.h"         // Insert file in current directory
#define X some text         // Replace X with some text
#define F(a,b) a+b          // Replace F(1,2) with 1+2
#define X \
 some text                  // Multiline definition
#undef X                    // Remove definition
#if defined(X)              // Conditional compilation (#ifdef X)
#else                       // Optional (#ifndef X or #if !defined(X))
#endif                      // Required after #if, #ifdef

Literals

255, 0377, 0xff             // Integers (decimal, octal, hex)
2147483647L, 0x7fffffffl    // Long (32-bit) integers
123.0, 1.23e2               // double (real) numbers
'a', '\141', '\x61'         // Character (literal, octal, hex)
'\n', '\\', '\'', '\"'      // Newline, backslash, single quote, double quote
"string\n"                  // Array of characters ending with newline and \0
"hello" "world"             // Concatenated strings

Declarations

short s; long l;            // Usually 16 or 32 bit integer (int may be either)
signed char s=-1;           // char might be either
unsigned long x =
  0xffffffffL;              // short, int, long are signed
float f; double d;          // Single or double precision real (never unsigned)
bool b=true;                // true or false, may also use int (1 or 0)
int a, b, c;                // Multiple declarations
int a[10];                  // Array of 10 ints (a[0] through a[9])
int a[]={0,1,2};            // Initialized array (or a[3]={0,1,2}; )
int a[2][2]={{1,2},{4,5}};  // Array of array of ints
char s[]="hello";           // String (6 elements including '\0')
std::string s = R"(Hello
World)";                    // Creates string object with value "Hello\nWorld"
char* s="hello";            // s points to unnamed array containing "hello"
void* p=nullptr;            // Address of untyped memory (nullptr is 0)
int& r=x;                   // r is a reference to (alias of) int x
enum weekend {SAT,SUN};     // weekend is a type with values SAT and SUN
enum weekend day;           // day is a variable of type weekend
enum weekend{SAT=0,SUN=1};  // Explicit representation as int
enum {SAT,SUN} day;         // Anonymous enum
enum class Color {Red,Blue};// Color is a strict type with values Red and Blue
Color x = Color::Red;       // Assign Color x to red
typedef String char*;       // String s; means char* s;
const int c=3;              // Constants must be initialized, cannot assign to
const int* p=a;             // Contents of p (elements of a) are constant
int* const p=a;             // p (but not contents) are constant
const int* const p=a;       // Both p and its contents are constant
const int& cr=x;            // cr cannot be assigned to change x
int8_t,uint8_t,int16_t,
uint16_t,int32_t,uint32_t,
int64_t,uint64_t            // Fixed length standard types
auto it = m.begin();        // Declares it to the result of m.begin()
auto const param = config["param"];
                            // Declares it to the const result
auto& s = singleton::instance();
                            // Declares it to a reference of the result

STORAGE Classes

static int x;               // Global lifetime even if local scope
extern int x;               // Information only, declared elsewhere

Statements

{                           // A block is a single statement
    int x;                  // Scope of x is from declaration to end of block
}
if (x) a;                   // If x is true (not 0), evaluate a
else if (y) b;              // If not x and y (optional, may be repeated)
else c;                     // If not x and not y (optional)

while (x) a;                // Repeat 0 or more times while x is true

for (x; y; z) a;            // Equivalent to: x; while(y) {a; z;}

for (x : y) a;              // Range-based for loop e.g.
                            // for (auto& x in someList) x.y();

do a; while (x);            // Equivalent to: a; while(x) a;

switch (x) {                // x must be int
    case X1: a;             // If x == X1 (must be a const), jump here
    case X2: b;             // Else if x == X2, jump here
    default: c;             // Else jump here (optional)
}
break;                      // Jump out of while, do, or for loop, or switch
continue;                   // Jump to bottom of while, do, or for loop
return x;                   // Return x from function to caller
try { a; }
catch (T t) { b; }          // If a throws a T, then jump here
catch (...) { c; }          // If a throws something else, jump here

Functions

f();                        // Default return type is int
inline f();                 // Optimize for speed
f() { statements; }         // Function definition (must be global)
T operator+(T x, T y);      // a+b (if type T) calls operator+(a, b)
T operator-(T x);           // -a calls function operator-(a)
T operator++(int);          // postfix ++ or -- (parameter ignored)
extern "C" {void f();}      // f() was compiled in C

------------------------------------------
int var=5;
void print(int * refvar=&var){
std::cout<<"var "<<*refvar<<std::endl;
}
int main(){
print();
}
int main()  { statements... }     // or
int main(int argc, char* argv[]) { statements... }

Operators :: . .* ?: can not overloaded.

Expressions

Operators are grouped by precedence, highest first. Unary operators and assignment evaluate right to left. All others are left to right. Precedence does not affect order of evaluation, which is undefined. There are no run time checks for arrays out of bounds, invalid pointers, etc.

T::X                        // Name X defined in class T
N::X                        // Name X defined in namespace N
::X                         // Global name X

p-> x                       // Member x of struct or class pointed to by p
x++                         // Add 1 to x, evaluates to original x (postfix)
x--                         // Subtract 1 from x, evaluates to original x
typeid(x)                   // Type of x
typeid(T)                   // Equals typeid(x) if x is a T
dynamic_cast< T>(x)         // Converts x to a T, checked at run time.
static_cast< T>(x)          // Converts x to a T, not checked
reinterpret_cast< T>(x)     // Interpret bits of x as a T
const_cast< T>(x)           // Converts x to same type T but not const

sizeof x                    // Number of bytes used to represent object x
sizeof(T)                   // Number of bytes to represent type T
~x                          // Bitwise complement of x
!x                          // true if x is 0, else false (1 or 0 in C)
-x                          // Unary minus
+x                          // Unary plus (default)
&x                          // Address of x
*p                          // Contents of address p (*&x equals x)
new T                       // Address of newly allocated T object
new T(x, y)                 // Address of a T initialized with x, y
new T[x]                    // Address of allocated n-element array of T
delete p                    // Destroy and free object at address p
delete[] p                  // Destroy and free array of objects at p
(T) x                       // Convert x to T (obsolete, use .._cast<T>(x))

x % y                       // Modulo (result has sign of x)

x << y                      // x shifted y bits to left (x * pow(2, y))
x >> y                      // x shifted y bits to right (x / pow(2, y))

x < y                       // Less than
x <= y                      // Less than or equal to
x > y                       // Greater than
x >= y                      // Greater than or equal to

x & y                       // Bitwise and (3 & 6 is 2)
x ^ y                       // Bitwise exclusive or (3 ^ 6 is 5)
x | y                       // Bitwise or (3 | 6 is 7)
x && y                      // x and then y (evaluates y only if x (not 0))
x || y                      // x or else y (evaluates y only if x is false (0))
x = y                       // Assign y to x, returns new value of x
x += y                      // x = x + y, also -= *= /= <<= >>= &= |= ^=
x ? y : z                   // y if x is true (nonzero), else z
throw x                     // Throw exception, aborts if not caught
x , y                       // evaluates x and y, returns y (seldom used)

Classes

class T {                   // A new type
private:                    // Section accessible only to T's member functions
protected:                  // Also accessible to classes derived from T
public:                     // Accessible to all
    int x;                  // Member data
    void f();               // Member function
    void g() {return;}      // Inline member function
    void h() const;         // Does not modify any data members
    int operator+(int y);   // t+y means t.operator+(y)
    int operator-();        // -t means t.operator-()
    T(): x(1) {}            // Constructor with initialization list
    T(const T& t): x(t.x) {}// Copy constructor
    T& operator=(const T& t)
    {x=t.x; return *this; } // Assignment operator
    ~T();                   // Destructor (automatic cleanup routine)
    explicit T(int a);      // Allow t=T(3) but not t=3
    T(float x): T((int)x) {}// Delegate constructor to T(int)
    operator int() const
    {return x;}             // Allows int(t)
    friend void i();        // Global function i() has private access
    friend class U;         // Members of class U have private access
    static int y;           // Data shared by all T objects
    static void l();        // Shared code.  May access y but not x
    class Z {};             // Nested class T::Z
    typedef int V;          // T::V means int
};
void T::f() {               // Code for member function f of class T
    this->x = x;}           // this is address of self (means x=x;)
int T::y = 2;               // Initialization of static member (required)
T::l();                     // Call to static member
T t;                        // Create object t implicit call constructor
t.f();                      // Call method f on object t

struct T {                  // Equivalent to: class T { public:
  virtual void i();         // May be overridden at run time by derived class
  virtual void g()=0; };    // Must be overridden (pure virtual)
class U: public T {         // Derived class U inherits all members of base T
  public:
  void g(int) override; };  // Override method g
class V: private T {};      // Inherited members of T become private
class W: public T, public U {};
                            // Multiple inheritance
class X: public virtual T {};
                            // Classes derived from X have base T directly

------------------------------------

class shape {
public :
 float pi;
shape(){
std::cout<<"shape constructor "<<" setting value of pi"<<std::endl;
pi=3.14;
}
~shape(){
std::cout<<" deconstructor of shape "<<" now pi was destroyed after destroyed of square_ip "<<std::endl;

}
};
class rectangle{
public:
rectangle(){
std::cout<<"rectangle constructor"<<std::endl;
}
~rectangle(){
std::cout<<"deconstructor of rectangle"<<std::endl;
}
};
class square  :public shape,public rectangle{
public:
float  square_pi;
square(){
square_pi=pi;
std::cout<<"square constructor "<<"pi value is ready  square_pi : "<< square_pi <<std::endl;
}
~square(){
std::cout<<" deconstruct of square "<<"square_pi was destroyed first " <<std::endl;

}
};

int main(){

square obj;
//obj.method();
//obj.method2();
std::cout<<"------------------start destroying-------------------------------------" <<std::endl;
}


All classes have a default copy constructor, assignment operator, and destructor, which perform the corresponding operations on each data member and each base class as shown above. There is also a default no-argument constructor (required to create arrays) if the class has no constructors. Constructors, assignment, and destructors do not inherit.

Templates

template <class T> T f(T t);// Overload f for all types
template <class T> class X {// Class with type parameter T
  X(T t); };                // A constructor
template <class T> X<T>::X(T t) {}
                            // Definition of constructor
X<int> x(3);                // An object of type "X of int"
template <class T, class U=T, int n=0>
                            // Template with default parameters

Namespaces

namespace N {class T {};}   // Hide name T
N::T t;                     // Use name T in namespace N
using namespace N;          // Make T visible without N::

memory (dynamic memory management)

#include <memory>           // Include memory (std namespace)
shared_ptr<int> x;          // Empty shared_ptr to a integer on heap. Uses reference counting for cleaning up objects.
x = make_shared<int>(12);   // Allocate value 12 on heap
shared_ptr<int> y = x;      // Copy shared_ptr, implicit changes reference count to 2.
cout << *y;                 // Dereference y to print '12'
if (y.get() == x.get()) {   // Raw pointers (here x == y)
    cout << "Same";  
}  
y.reset();                  // Eliminate one owner of object
if (y.get() != x.get()) { 
    cout << "Different";  
}  
if (y == nullptr) {         // Can compare against nullptr (here returns true)
    cout << "Empty";  
}  
y = make_shared<int>(15);   // Assign new value
cout << *y;                 // Dereference x to print '15'
cout << *x;                 // Dereference x to print '12'
weak_ptr<int> w;            // Create empty weak pointer
w = y;                      // w has weak reference to y.
if (shared_ptr<int> s = w.lock()) { // Has to be copied into a shared_ptr before usage
    cout << *s;
}
unique_ptr<int> z;          // Create empty unique pointers
unique_ptr<int> q;
z = make_unique<int>(16);   // Allocate int (16) on heap. Only one reference allowed.
q = move(z);                // Move reference from z to q.
if (z == nullptr){
    cout << "Z null";
}
cout << *q;
shared_ptr<B> r;
r = dynamic_pointer_cast<B>(t); // Converts t to a shared_ptr<B>

math.h, cmath (floating point math)

#include <cmath>            // Include cmath (std namespace)
sin(x); cos(x); tan(x);     // Trig functions, x (double) is in radians
asin(x); acos(x); atan(x);  // Inverses
atan2(y, x);                // atan(y/x)
sinh(x); cosh(x); tanh(x);  // Hyperbolic sin, cos, tan functions
exp(x); log(x); log10(x);   // e to the x, log base e, log base 10
pow(x, y); sqrt(x);         // x to the y, square root
ceil(x); floor(x);          // Round up or down (as a double)
fabs(x); fmod(x, y);        // Absolute value, x mod y

assert.h, cassert (Debugging Aid)

Exceptions are used for run-time error conditions (IO errors, out of memory, can't get a database connection, etc.).

Assertions are used for coding errors (this method doesn't accept nulls, and the developer passed one anyway).

#include <cassert>        // Include iostream (std namespace)
assert(e);                // If e is false, print message and abort
#define NDEBUG            // (before #include <assert.h>), turn off assert

iostream.h, iostream (Replaces stdio.h)

#include <iostream>         // Include iostream (std namespace)
cin >> x >> y;              // Read words x and y (any type) from stdin
cout << "x=" << 3 << endl;  // Write line to stdout
cerr << x << y << flush;    // Write to stderr and flush
c = cin.get();              // c = getchar();
cin.get(c);                 // Read char
cin.getline(s, n, '\n');    // Read line into char s[n] to '\n' (default)
if (cin)                    // Good state (not EOF)?
                            // To read/write any type T:
istream& operator>>(istream& i, T& x) {i >> ...; x=...; return i;}
ostream& operator<<(ostream& o, const T& x) {return o << ...;}

fstream.h, fstream (File I/O works like cin, cout as above)

#include <fstream>          // Include filestream (std namespace)
ifstream f1("filename");    // Open text file for reading
if (f1)                     // Test if open and input available
    f1 >> x;                // Read object from file
f1.get(s);                  // Read char or line
f1.getline(s, n);           // Read line into string s[n]
ofstream f2("filename");    // Open file for writing
if (f2) f2 << x;            // Write to file

string (Variable sized character array)

#include <string>         // Include string (std namespace)
string s1, s2="hello";    // Create strings
s1.size(), s2.size();     // Number of characters: 0, 5
s1 += s2 + ' ' + "world"; // Concatenation
s1 == "hello world"       // Comparison, also <, >, !=, etc.
s1[0];                    // 'h'
s1.substr(m, n);          // Substring of size n starting at s1[m]
s1.c_str();               // Convert to const char*
s1 = to_string(12.05);    // Converts number to string
getline(cin, s);          // Read line ending in '\n'

vector (Variable sized array/stack with built in memory allocation)

#include <vector>         // Include vector (std namespace)
vector<int> a(10);        // a[0]..a[9] are int (default size is 0)
vector<int> b{1,2,3};        // Create vector with values 1,2,3
a.size();                 // Number of elements (10)
a.push_back(3);           // Increase size to 11, a[10]=3
a.back()=4;               // a[10]=4;
a.pop_back();             // Decrease size by 1
a.front();                // a[0];
a[20]=1;                  // Crash: not bounds checked
a.at(20)=1;               // Like a[20] but throws out_of_range()
for (int& p : a)
  p=0;                    // C++11: Set all elements of a to 0
for (vector<int>::iterator p=a.begin(); p!=a.end(); ++p)
  *p=0;                   // C++03: Set all elements of a to 0
vector<int> b(a.begin(), a.end());  // b is copy of a
vector<T> c(n, x);        // c[0]..c[n-1] init to x
T d[10]; vector<T> e(d, d+10);      // e is initialized from d

deque (Array stack queue)

deque<T> is like vector<T>, but also supports:

#include <deque>          // Include deque (std namespace)
a.push_front(x);          // Puts x at a[0], shifts elements toward back
a.pop_front();            // Removes a[0], shifts toward front

utility (pair)

#include <utility>        // Include utility (std namespace)
pair<string, int> a("hello", 3);  // A 2-element struct
a.first;                  // "hello"
a.second;                 // 3

map (associative array - usually implemented as binary search trees - avg. time complexity: O(log n))

#include <map>            // Include map (std namespace)
map<string, int> a;       // Map from string to int
a["hello"] = 3;           // Add or replace element a["hello"]
for (auto& p:a)
    cout << p.first << p.second;  // Prints hello, 3
a.size();                 // 1

unordered_map (associative array - usually implemented as hash table - avg. time complexity: O(1))

#include <unordered_map>  // Include map (std namespace)
unordered_map<string, int> a; // Map from string to int
a["hello"] = 3;           // Add or replace element a["hello"]
for (auto& p:a)
    cout << p.first << p.second;  // Prints hello, 3
a.size();                 // 1

set (store unique elements - usually implemented as binary search trees - avg. time complexity: O(log n))

#include <set>            // Include set (std namespace)
set<int> s;               // Set of integers
s.insert(123);            // Add element to set
if (s.find(123) != s.end()) // Search for an element
    s.erase(123);
cout << s.size();         // Number of elements in set

unordered_set (store unique elements - usually implemented as a hash set - avg. time complexity: O(1))

#include <unordered_set>  // Include set (std namespace)
unordered_set<int> s;     // Set of integers
s.insert(123);            // Add element to set
if (s.find(123) != s.end()) // Search for an element
    s.erase(123);
cout << s.size();         // Number of elements in set

algorithm (A collection of 60 algorithms on sequences with iterators)

#include <algorithm>      // Include algorithm (std namespace)
min(x, y); max(x, y);     // Smaller/larger of x, y (any type defining <)
swap(x, y);               // Exchange values of variables x and y
sort(a.begin(), a.end()); // Sort vector or deque
binary_search(a, a + 10, 50);
reverse(a.begin(), a.end()); // Reverse vector or deque
int z = count(v.begin(), v.end(), 9);
is_sorted(v.begin(), v.end());
auto max = max_element(v.begin(), v.end());
fill(v6.begin(), (v6.begin() + 3), 15);
for_each(v3.begin(), v3.end(), [](const int &i){ cout << "element : " << i << endl; });
 auto x = find_if(v.begin(), v.end(),  [](int i) { return i % 2 == 0; });
        
        ### for containers
auto y = search(v.begin(), v.end(), v2.begin(), v2.end());// v= 10 20 30 40 50 60 70 80 90 ? and v2 =40 50 60
                                                          // y=          ^        and if not found y iterate on ?
        
     
auto afterEnd_iterator = unique(v.begin(), v.end()); //  int v[] = {10,20,20,20,20,20,30,30,20,20,10};
                                                    //afterEnd_iterator = // 10 20 30 20 10 ?  ?  ?  ?
                                                         //                                 ^
int acc = accumulate(v.begin(), v.end(), 0); //add 0 value to the accumulated value


        copy(v.begin(), v.end(), back_inserter(v3));

         auto min = minmax_element(v6.begin(), v6.begin());

        auto mh = mismatch(v.begin(), v.end(), v4);
        auto eq = equal(v6.begin(), v6.end(), v5.begin());
        auto c = minmax({1, 5, 3, 8});

chrono (Time related library)

#include <chrono>         // Include chrono
using namespace std::chrono; // Use namespace
auto from =               // Get current time_point
  high_resolution_clock::now();
// ... do some work       
auto to =                 // Get current time_point
  high_resolution_clock::now();
using ms =                // Define ms as floating point duration
  duration<float, milliseconds::period>;
                          // Compute duration in milliseconds
cout << duration_cast<ms>(to - from)
  .count() << "ms";

chrono in more details

int main()
{
  /*  std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<int, std::ratio<1, 1000000000L>>> start = std::chrono::system_clock::now();
   std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<int, std::nano>> start = std::chrono::system_clock::now();
   std::chrono::time_point<std::chrono::system_clock, std::chrono::system_clock::duration> start = std::chrono::system_clock::now();
   std::chrono::time_point<std::chrono::system_clock> start = std::chrono::system_clock::now();
   std::chrono::system_clock::time_point start = std::chrono::system_clock::now(); */
  auto before_start = std::chrono::system_clock::now();
  auto start = std::chrono::system_clock::now();
  auto end = std::chrono::system_clock::now();
  time_t w = std::chrono::system_clock::to_time_t(end); // long w = end.time_since_epoch().count()
  end = std::chrono::system_clock::from_time_t(w);
  std::chrono::duration<size_t, std::ratio<1, 1000000000L>> the_duration = end - start; // auto ee = duration_cast<ms>(dd);
  before_start += the_duration;
  auto duration_minu = std::chrono::duration_cast<std::chrono::minutes>(the_duration);
  // operator overloadong return duration
}

thread (Multi-threading library)

#include <thread>         // Include thread
unsigned c = 
  hardware_concurrency(); // Hardware threads (or 0 for unknown)
auto lambdaFn = [](){     // Lambda function used for thread body
    cout << "Hello multithreading";
};
thread t(lambdaFn);       // Create and run thread with lambda
t.join();                 // Wait for t finishes

// --- shared resource example ---
mutex mut;                         // Mutex for synchronization
condition_variable cond;           // Shared condition variable
const char* sharedMes              // Shared resource
  = nullptr;
auto pingPongFn =                  // thread body (lambda). Print someone else's message
  [&](const char* mes){
    while (true){
      unique_lock<mutex> lock(mut);// locks the mutex 
      do {                
        cond.wait(lock, [&](){     // wait for condition to be true (unlocks while waiting which allows other threads to modify)        
          return sharedMes != mes; // statement for when to continue
        });
      } while (sharedMes == mes);  // prevents spurious wakeup
      cout << sharedMes << endl;
      sharedMes = mes;       
      lock.unlock();               // no need to have lock on notify 
      cond.notify_all();           // notify all condition has changed
    }
  };
sharedMes = "ping";
thread t1(pingPongFn, sharedMes);  // start example with 3 concurrent threads
thread t2(pingPongFn, "pong");
thread t3(pingPongFn, "boing");

future (thread support library)

#include <future>         // Include future
function<int(int)> fib =  // Create lambda function
  [&](int i){
    if (i <= 1){
      return 1;
    }
    return fib(i-1) 
         + fib(i-2);
  };
future<int> fut =         // result of async function
  async(launch::async, fib, 4); // start async function in other thread
// do some other work 
cout << fut.get();        // get result of async function. Wait if needed.

share the same memory

enum class type
{
  _3G,
  _4G,
  _5G,
};
union network
{
  int G3;
  int G4;
  int G5;
};
struct network_type
{
  network _network;
  type net;
};

network_type net_work;

int main()
{
  net_work.net = type::_3G;
  if (net_work.net == type::_3G)
    net_work._network.G3 = 50;
}

move semantic

Rvalue

example :

literal : 5,7,9 return from function x=8;// 8 is Rvalue

Lvalue : has name or address

move semantic

​ it is just type casting output =static_cast< T &&>(input) ; note that we need to define move constructor to avoid binding member of object to pointers without set the orgin to nullptr to avoid potional buggs by doing this we achieve the meaning of move sementic not just casting as std::move to get Rvalue reference from variable

  • if no move constructor due to delete move constractor or define copy constructor --> compiler will call copy constructor instead of move construactor
  • the elements of && obj(out from std::move) is lvalue so in move construactor you should use std::move for each element so default move constructor do this
  • we can say that shaping of the statement of move constructor by passing rvalue reference to distanguish between calling move constructor or copy constructor
T&& var =5
binding Rvalue reference

T var= Rvalue reference

T& var =Rvalue reference

where input is variable and output may be variable or lvalue reference  


```cpp

##example of using move sematic :
struct mynote
{
  int *data;
  int size;
};

void just_move(mynote &v, mynote &&w)
{
 v.data = w.data; // we move the sematic value to 
 v.size = w.size;//we move //5 in w.size and bind it withv.size
 w.size = 0;// not bind to 5 any more
 w.data=nullptr //prevent the e to point into the same address
}
e.size=5;
just_move(r,move(e));
//e.size==0; and e.data=nullptr 
//r.size=5

---------------------------------------------
//here you are not construct new obj you just binding one to aready existed one


class Cents
{
private:
    int m_cents{};

public:
Cents(const Cents & other)=delete;
Cents(Cents && other)=delete;
Cents& operator=(const Cents& other)=delete; // copy assignment
Cents& operator=( Cents&& other)=delete; // copy assignment

    Cents(int cents): m_cents { cents }
    {}
    int getCents() const { return m_cents; }

};


int main()
{

//test for buit-in datatype
int && r_ref=50;
int var=50;
int & l_ref=r_ref;
int & l_ref2=var;
int && r_ref2=static_cast<int&&>(var);
int & l_ref3=r_ref2;
int var2=l_ref;
int var3=r_ref2;
//int && r_ref2=std::move(var);

Cents obj{5};
Cents&& obj2=std::move(obj);
Cents && obj_r_ref=Cents{6};
Cents  obj_var=Cents{6};
Cents & obj_l_ref=obj_r_ref;
Cents & obj_l_ref2=obj_var;
Cents && obj_r_ref2=static_cast<Cents&&>(obj_var);//or use std::move()
std::cout<<obj_r_ref2.getCents();

}

About

Modern C++ Cheatsheet

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 100.0%