return_type functionName(/* params */) try { // body } catch (exception_type1&) {
// handler
}
catch (exception_type1&) {
// handler
}
return_type functionName(/* params */) noexcept { // body }
inline return_type functionName(/* params */) {}
inline type variableName /* = initializer */;
// use1.cpp
#include "common.h"
...
// common.h
void noop() {}
int answer = 44;
// use2.cpp
#include "common.h"
...
Multiple definition error
inline return_type functionName(/* params */) {}
inline type variableName /* = initializer */;
// 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;
inline return_type functionName(/* params */) {}
inline type variableName /* = initializer */;
// use1.cpp
#include "common.h"
...
// common.h
inline void noop();
inline int answer;
// use2.cpp
#include "common.h"
...
Inline
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;
}
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);
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
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);
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
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&
}
auto functionName(/* params */) -> return_type { // body }
return_type functionName(/* params */) { // body }
#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
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
type arrayName[constantExpr];
std::array<type, constantExpr> arrayName;
switch (value) { case constantExpr: //... }
if constexpr (constantExpr) { //... }
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);
}
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);
}
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);
}
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
[]{}
[]{ return 25; }
[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"; }
[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"; }
[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"; }
[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)]
[&] [=]
[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"; }
[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) ]
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
[]() [[noreturn]] { std::abort(); }
[]() [[nodiscard]] { return 12; }
[]() [[deprecated]] { printf("12"); }
[captures]<tparams>(params) specifiers noexcept attrs -> ret { body }
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](){};