random things

inv: \R\setminus\{0\}\rightarrow\R \newline
inv(x) = \frac{1}x
double inv(double x)
{
  return 1.0 / x;
}
  double hmm = inv(0.0); // == ?
  • compile error
  • undefined behaviour
  • infinity
  • NaN
0 \notin D_{inv} \implies inv(0)\uparrow

preconditions and postconditions

preconditions and postconditions

inv: \R\setminus\{0\}\rightarrow\R \newline
inv(x) = \frac{1}x
double inv(double x)
{
  return 1.0 / x;
}
  double hmm = inv(0.0); // == ?
  • compile error
  • undefined behaviour
  • infinity
  • NaN
0 \notin D_{inv} \implies inv(0)\uparrow
double inv(double x) [[expects: i != 0.0]]
{
  return 1.0 / x;
}

contracts

C++20

#include <cassert>

double inv(double x)
{
  assert(x != 0);
  return 1.0 / x;
}

assertions

  double hmm = inv(0.0); // assertion failed

assertions

assert(condition)
static_assert(condition, message)
static_assert(condition)
  • preconditions
  • postconditions
  • invariants
condition

Integral types

char
short
int
long
long long
signed
unsigned
unsigned char

binary

decimal

13
245
18
192
0
256
00001101
11110101
00010010
11000000
00000000
11111111
signed char

U2

decimal

13
245
18
192
0
256
11110011
--------
11101110
--------
00000000
--------
[0, 255]
[-128, 127]

Integral types

overflow: defined

overflow: undefined

bitwise and logical operations

NOT

and

or

xor

lshift

rshift

bitwise

logical

!a
a && b
a || b
~a
a & b
a | b
a ^ b
a << n
a >> n
(a != b)

alternative operator tokens

&&
&=
&
|
~
!
!=
||
|=
^
^=
and
and_eq
bitand
bitor
compl
not
not_eq
or
or_eq
xor
xor_eq

casts

c-style case

static_cast
reinterpret_cast
const_cast
dynamic_cast

ternary operator

x = condition ? true_value : false_value;
type ternary(bool condition, type true_value, type false_value)
{
  if (condition)
    return true_value;
  else
    return false_value;
}

 

x = ternary(condition, true_value, false_value);
\Leftrightarrow
 
 

ternary operator

int max(int a, int b)
{
  if (a < b)
  {
    return a;
  }
  else
  {
    return b;
  }
}
int max(int a, int b)
{
  return a < b ? a : b;
}

Comma operator

x = expression1, expression2, /* ..., */ expressionN;
expression1;
expression2;
/* ...; */
x = expressionN;
 
 
\Leftrightarrow

Comma operator

void print_pows(int n, int base)
{
    for (int i = 0, pow = 1; i < n; ++i)
    {
        std::cout << pow;
        pow *= base;
    }
}
void print_pows(int n, int base)
{
    for (int i = 0, pow = 1; i < n; ++i, pow *= base)
    {
        std::cout << pow;
    }
}

e p

x r

p o

r g

e r

s a

s m

i m

o i

n n

   G

std::tuple<std::optional<float>, std::optional<float>>
quadric_expression(const float a, const float b, const float c)
{
    const float delta = b * b - 4 * a * c, 
           sqrt_delta = delta >= 0 ? sqrt(delta) : -1;
    return {
        delta >= 0 ? std::optional{(-b - sqrt_delta) / 2 * a} : std::nullopt,
        delta >  0 ? std::optional{(-b + sqrt_delta) / 2 * a} : std::nullopt
    };
}

std::tuple<std::optional<float>, std::optional<float>>
quadric_statement(const float a, const float b, const float c)
{
    const float delta = b * b - 4 * a * c;
    if (delta > 0)
    {
        const float sqrt_delta = sqrt(delta);
        const float x1 = (-b - sqrt_delta) / 2 * a;
        const float x2 = (-b + sqrt_delta) / 2 * a;
        return { x1, x2 };
    }
    else if (delta < 0)
    {
        return { std::nullopt, std::nullopt };
    }
    else // delta == 0
    {
        const float sqrt_delta = sqrt(delta);
        const float x1 = (-b - sqrt_delta) / 2 * a;
        return { x1, std::nullopt };
    }
}

type aliases

typedef type alias;
using alias = type;
 
 
\Leftrightarrow

type aliases

using int_ptr = int*;
using my_func_ptr = int*(*)(int, int);
using double_10_ar = double[10];
typedef int* int_ptr;
typedef int*(*my_func_ptr)(int, int);
typedef double double_10_ar[10];
\Leftrightarrow
template <typename T, size_t SIZE>
using raw_array = T[SIZE];
using namespace ns;
using namespace ns = long_namespace_name;
using namespace
auto

structured binding

variable type deduction

return type deduction

generic lamdas

abbreviated function templates

functions with trailing return type

decltype(auto)

non type template parameter with deduced type

auto

variable type deduction

auto msg = "Hello";
// const char*
  
auto x = fib();
// int

auto&& y = 3; 
// int&&

auto nums = std::vector{1, 2, 3, 4};
//std::vector<int>

auto begin = nums.begin();
//std::vector<int>::iterator

for (auto& element : nums) // int&
{
  element += 2;
}

structured binding

decltype(auto)
auto
struct vec2
{     
  float x, y;
} v{ 1.0, 2.0 };

auto [right, up] = v;
right += up;
// v.x == 1.0

auto& [right_ref, up_ref] = v;
right_ref += up_ref;
// v.x == (1.0 + 2.0)

structured binding

const int components[10] = { 1, 2, 3, 4 };
const auto& [x, y, z, w] = components;
struct divide_result
{
  int quotient;
  int remaineder;
}

divide_result
divide(int dividend, int divisor)
{
  assert(divisor != 0);

  return {
    dividend / divisor,
    dividend % divisor
  };
}

void use()
{
  auto result = divide(7, 3);
  int quot1 = divide.quotient,
      rmnd1 = result.remainder;

  int quot2, rmnd2;
  std::tie(quot2, rmnd2) = divide(7, 3);

  auto [quot3, rmnd3] = divide(7, 3);
}
std::map<std::string, int> ages = get_a();

int age_sum = 0;
for (const auto& [name, age] : ages)
{
  age_sum += age;
}
decltype(auto)
auto
auto x1 = get_int(); // int
auto x2 = get_int_ref(); // int
auto x3 = get_const_int_ref(); // int

auto& y1 = get_int(); // error!!!
auto& y2 = get_int_ref(); // int&
auto& y3 = get_const_int_ref(); // const int&

decltype(auto) z1 = get_int(); // int
decltype(auto) z2 = get_int_ref(); // int&
decltype(auto) z3 = get_const_int_ref(); // const int&
decltype(auto)
int get_int();
int& get_int_ref();
const int& get_const_int_ref();

enumerations

enum class VertexState
{
  Unvisited, Preordered, Postordered
};

std::vector<VertexState> vertices;

vertices[i] = VertexState::Unvisited;
vertices[i] = VertexState::Preordered;
vertices[i] = VertexState::Postordered;
#define Unvisited 0
#define Preordered 0
#define Postordered 0

std::vector<int> vertices;

vertices[i] = Unvisited;
vertices[i] = Preordered;
vertices[i] = Postordered;

enumerations

enum class Fruit : int
{
  Apple   /* = 0 */,
  Samsung /* = 1 */,
  Huawei  /* = 2 */,
  Xiaomi  /* = 3 */,
};
enum class Fruit : short
{
  Apple      = N,
  Samsung /* = N + 1 */,
  Huawei  /* = N + 2 */,
  Xiaomi  /* = N + 3 */,
};
enum /*class*/ Fruit
{
  Apple,
  Samsung,
  Huawei,
  Xiaomi,
};

enum /*class*/ Corp
{
  Apple, // error!!!
  Banana,
  Pear,
  Grape,
};
static_assert(static_cast<int>(Fruit::Apple) == 0);
static_assert(static_cast<int>(Fruit::Samsung) == 1);
static_assert(static_cast<int>(Fruit::Huawei) == 2);
static_assert(static_cast<int>(Fruit::Xiaomi) == 3);
static_assert(static_cast<Fruit>(0) == Fruit::Apple);
static_assert(static_cast<Fruit>(1) == Fruit::Samsung);
static_assert(static_cast<Fruit>(2) == Fruit::Huawei);
static_assert(static_cast<Fruit>(3) == Fruit::Xiaomi);
struct s {
  enum class e {
  }
}
#include <iostream>

int main()
{
  std::cout << "Welcome to The Useless Command!\n"
  			<< "Do you want to see The Useless Message? [y/n]";
  char c;
  std::cin >> c;
  if (c == 'y' || c == 'Y')
  {
    std::cout << "You are witnessing: \"The Useless Message\"\n";
  }
  else if (c == 'n' || c == 'N')
  {
    std::cout << "Goodbye, then...\n";
  }
  else
  {
    std::cout << "Sorry, I didn't get that.\n";
  }
}
switch
#include <iostream>

int main()
{
  std::cout << "Welcome to The Useless Command!\n"
  			<< "Do you want to see The Useless Message? [y/n]";
  char c;
  std::cin >> c;
  switch (c)
  {
  case 'y': [[fallthrough]];
  case 'Y':
    std::cout << "You are witnessing: \"The Useless Message\"\n";
    break;
  case 'n': [[fallthrough]];
  case 'N':
    std::cout << "Goodbye, then...\n";
    break;
  default:
    std::cout << "Sorry, I didn't get that.\n";
    break;
}
switch
switch
#include <iostream>

int main()
{
  std::cout << "Welcome to The Useless Command!\n"
  			<< "Do you want to see The Useless Message? [y/n]";
  string s;
  std::cin >> s;
  if (s == "y" || s == "Y" || s == "yes" || s = "Yes")
  {
    std::cout << "You are witnessing: \"The Useless Message\"\n";
  }
  else if (s == "n" || s == "N" || s == "no || s = "No)
  {
    std::cout << "Goodbye, then...\n";
  }
  else
  {
    std::cout << "Sorry, I didn't get that.\n";
  }
}
switch
#include <iostream>

int main()
{
  std::cout << "Welcome to The Useless Command!\n"
  			<< "Do you want to see The Useless Message? [y/n]";
  string s;
  std::cin >> s;
  if (s == "y" || s == "Y" || s == "yes" || s = "Yes")
  {
  	std::cout << "You are witnessing: \"The Useless Message\"\n"
  }
  else if (s == "n" || s == "N" || s == "no || s = "No)
  {
    std::cout << "Goodbye, then...\n";
  }
  else
  {
    std::cout << "Sorry, I didn't get that.\n";
  }
}
switch(s)
switch
char c;
switch(c) {...}
int n;
switch(n) {...}
enum class Fruit 
{
	Apple,
    Samsung, 
    ...
};

Fruit n;
switch(n)
{
case Fruit::Apple:
  apple_tree().harvest();
  break;
case Fruit::Samsung:
  ...
default:
  ...
}
unsigned long n;
switch(n) {...}
bool v;
switch(v) {...}

random things

Random Things

By Jan Bielak

Random Things

A presentation about many different C++ features. It is presented here: https://www.youtube.com/watch?v=xvxlPMNQuRM .

  • 589