Functions
Functions
and exceptions
return_type functionName(/* params */) try { // body } catch (exception_type1&) {
// handler
}
catch (exception_type1&) {
// handler
}
return_type functionName(/* params */) noexcept { // body }
Functions
inline
inline return_type functionName(/* params */) {}
inline type variableName /* = initializer */;
and variables
// use1.cpp
#include "common.h"
...
// common.h
void noop() {}
int answer = 44;
// use2.cpp
#include "common.h"
...
Multiple definition error
Functions
inline
inline return_type functionName(/* params */) {}
inline type variableName /* = initializer */;
and variables
// use1.cpp
#include "common.h"
...
// common.h
void noop();
extern int answer;
// use2.cpp
#include "common.h"
...
Declaration & definition separation
// common.cpp
void noop() {}
int answer = 44;
Functions
inline
inline return_type functionName(/* params */) {}
inline type variableName /* = initializer */;
and variables
// use1.cpp
#include "common.h"
...
// common.h
inline void noop();
inline int answer;
// use2.cpp
#include "common.h"
...
Inline
Function
overloading
struct square {
float side;
}
struct triangle {
float base, height;
}
struct circle {
float radius;
}
float areaSquare(const square& s) {
return s.side * s.side;
}
float areaTriangle(const triangle& tri) {
return (tri.base * tri.height) / 2.0;
}
float areaCircle(const circle& c) {
return PI * c.radius * c.radius;
}
Function
overloading
struct square {
float side;
}
struct triangle {
float base, height;
}
struct circle {
float radius;
}
float area(const square& s) {
return s.side * s.side;
}
float area(const triangle& tri) {
return (tri.base * tri.height) / 2.0;
}
float area(const circle& c) {
return PI * c.radius * c.radius;
}
square s = ...;
triangle tri = ...;
circle c = ...;
float a1 = area(s);
float a2 = area(tri);
float a3 = area(c);
Function
overloading
int add( int a, int b) { return a + b; }
short add( short a, short b) { return a + b; }
float add( float a, float b) { return a + b; }
char add( char a, char b) { return a + b; }
(Templates)
float area( const square& s) { return s.side * s.side; }
float area(const triangle& tri) { return (tri.base * tri.height) / 2.0; }
float area( const circle& c) { return PI * c.radius * c.radius; }
(Methods, Polymorphism)
file openConnection(
const std::string& address) {
openConnection(address, ConnectionFlagsBit::None);
};
file openConnection(
const std::string& address,
ConnectionFlagsBit flags) {
openConnection(address, flags, std::chrono::milliseconds::zero())
}
file openConnection(
const std::string& address,
ConnectionFlagsBit flags,
const std::chrono::milliseconds& timeout);
(Default arguments)
add(2.0) ambiguous
Function
default
file openConnection(
const std::string& address) {
openConnection(address, ConnectionFlagsBit::None);
};
file openConnection(
const std::string& address,
ConnectionFlagsBit flags) {
openConnection(address, flags, std::chrono::milliseconds::zero())
}
file openConnection(
const std::string& address,
ConnectionFlagsBit flags,
const std::chrono::milliseconds& timeout);
arguments
file openConnection(
const std::string& address,
ConnectionFlagsBit flags = ConnectionFlagsBit::None,
const std::chrono::milliseconds& timeout = std::chrono::milliseconds::zero());
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
return type
const int x = 0;
auto f() {
return x;
}
decltype(auto) g() {
return static_cast<const int&>(x);
}
void use() {
auto n = f(); // int
decltype(auto) nd = f(); // int
auto m = g(); // int
decltype(auto) md = g(); // const int&
}
return type
trailing
auto functionName(/* params */) -> return_type { // body }
return_type functionName(/* params */) { // body }
compile-time
RUN-TIME
- performance
- compile time values
- instead of code generation / additional build steps
computation
constexpr
template Metaprogramming
Preprocessor
compile-time computation
computation
#ifndef HEADER_GUARD
#define HEADER_GUARD
#include <type_traits>
#include "myheader.h"
#define PI 3.1415926
#define ERROR_MSG "Exception access violation"
#define ADD(ARG1, ARG2) ((ARG1) + (ARG2))
#define STRINGIFY(ARG1) #ARG1
#define CONCAT(ARG1, ARG2) ARG1 ## ARG2
#define FWD(...) std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
#ifdef __APPLE__
#include "apple_specific.h"
#elif __linux__
#include "linux_specific.h"
#elif _WIN32
#include "windows_specific.h"
#else
#error Unsupported platform
#endif
#line 42
#endif // HEADER_GUARD
- Header guards
- Includes
- Constants
- Compile-time computation
- Source code transformation
- Cross-platform compatibility
- Platform detection
- Conditional compilation
- Reporting compilation errors
- Code generation support
Preprocessor
constexpr
template Metaprogramming
compile-time computation
constexpr
template Metaprogramming
Preprocessor
compile-time computation
constexpr
Variables
constexpr int TATTUQOLTUAE = 42;
constexpr double PI = 3.141592653;
constexpr auto message = "Hello World!";
constexpr auto numbers = { 1, 2, 3, 4, 5 }; // std::initializer_list<int>
constexpr auto [x, y] = func_returning_pair(); // ERROR
Functions
constepxr int ArraySize = 100;
constexpr std::array<int, ArraySize> fib_ar(int n) {
std::array<int, ArraySize> res{};
for (int i = 1; i < ArraySize; ++i) {
res[i] = res[i - 1] + res[i - 2];
}
return res;
}
constexpr int ArraySize = 100;
constexpr std::array<int, ArraySize> fib_ar(int n) {
std::array<int, ArraySize> res{};
for (int i = 1; i < ArraySize; ++i) {
res[i] = res[i - 1] + res[i - 2];
}
return res;
}
if constexpr (constantExpr)
If
constexpr
consteval
constinit
constexpr
uses
type arrayName[constantExpr];
std::array<type, constantExpr> arrayName;
switch (value) { case constantExpr: //... }
if constexpr (constantExpr) { //... }
arrays
templates
switch cases
compile-time computation
Functions
lambda
std::vector<int> v{2, 3, 4, 2, 5, 2, 1};
std::sort(v.begin(), v.end());
std::sort(v.begin(), v.end(), pred_gt);
std::sort(v.begin(), v.end(), pred_mod);
{1, 2, 2, 2, 3, 4, 5}
{5, 4, 3, 2, 2, 2, 1}
{3, 1, 4, 2, 2, 2, 5}
bool pred_gt(int x, int y) {
return x > y;
}
bool pred_mod(int x, int y) {
return (x % 3) < (y % 3);
}
Functions
lambda
bool pred_mod(int x, int y) {
return (x % 3) < (y % 3);
}
void foo() {
std::vector<int> v{2, 3, 4, 2, 5, 2, 1};
std::sort(v.begin(), v.end(), pred_mod);
}
bool pred_mod(int x, int y) {
return (x % 3) < (y % 3);
}
Functions
lambda
void foo() {
std::vector<int> v{2, 3, 4, 2, 5, 2, 1};
std::sort(v.begin(), v.end(),
[](int x, int y) {
return (x % 3) < (y % 3);
}
);
}
bool pred_mod(int x, int y) {
return (x % 3) < (y % 3);
}
Functions
lambda
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
Functions
lambda
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
[]{}
[]{ return 25; }
Functions
lambda
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
[](int x, int y){ return x + y; }
[](int x){ if (x % 2 == 0) return "EVEN"; else return "ODD"; }
Functions
lambda
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
[](int x, int y) -> int { return x + y; }
[](int x) -> const char* { if (x % 2 == 0) return "EVEN"; else return "ODD"; }
Functions
lambda
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
[](int x, int y) noexcept -> int { return x + y; }
[](int x) noexcept -> const char* { if (x % 2 == 0) return "EVEN"; else return "ODD"; }
Functions
lambda
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
void foo(int r) {
[](){
r = ...; //error
}();
}
void foo(int r) {
[r](){
r = ...; //ok
}();
}
[x, y, &z, &w /*...*/] [x = foo(name)]
[&] [=]
Functions
lambda
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
[m](int x, int y) noexcept -> int { return (x + y) % m; }
[&x]() noexcept -> const char* { if (x % 2 == 0) return "EVEN"; else return "ODD"; }
Functions
lambda
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
[m](int x, int y) noexcept -> void { m = x + y; }
[m](int x, int y) mutable noexcept -> void { m = x + y; }
int ar[ [](int x, int y) noexcept -> int { return x + y; }(2, 3) ]
int ar[ [](int x, int y) constexpr noexcept -> int { return x + y; }(2, 3) ]
Functions
lambda
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
[]() [[noreturn]] { std::abort(); }
[]() [[nodiscard]] { return 12; }
[]() [[deprecated]] { printf("12"); }
Functions
lambda
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
Functions
as variables
return_t func(param1_t, param2_t);
return_t (*ptr_name)(param1_t, param2_t) = &func;
void(*lambda1)() = [](){};
void(*lambda2)() = [x](){}; // error
auto ptr_name = &func;
auto lambda1 = [](){};
auto lambda2 = [x](){};
#include <functional>
std::function<return_t(param1_t, param2_t)> func_2 = func;
std::function<void()> lambda1 = [](){};
std::function<void()> lambda2 = [x](){};
Functions
Functions
By Jan Bielak
Functions
A presentation about noexcept functions, try catch functions, inline functions and variables, function overloading, default function parameters, lambdas (unnamed functions), function pointers, and constexpr (consteval,constinit) functions and variables in C++ as well as std::function. It is presented here: https://www.youtube.com/watch?v=Sqaocm3f7OY .
- 704