mirror of
https://github.com/AnthonyCalandra/modern-cpp-features.git
synced 2025-12-17 18:14:36 +03:00
Merge branch 'master' of github.com:AnthonyCalandra/modern-cpp-features
This commit is contained in:
59
CPP11.md
59
CPP11.md
@@ -13,7 +13,7 @@ C++11 includes the following new language features:
|
|||||||
- [auto](#auto)
|
- [auto](#auto)
|
||||||
- [lambda expressions](#lambda-expressions)
|
- [lambda expressions](#lambda-expressions)
|
||||||
- [decltype](#decltype)
|
- [decltype](#decltype)
|
||||||
- [template aliases](#template-aliases)
|
- [type aliases](#type-aliases)
|
||||||
- [nullptr](#nullptr)
|
- [nullptr](#nullptr)
|
||||||
- [strongly-typed enums](#strongly-typed-enums)
|
- [strongly-typed enums](#strongly-typed-enums)
|
||||||
- [attributes](#attributes)
|
- [attributes](#attributes)
|
||||||
@@ -33,6 +33,7 @@ C++11 includes the following new language features:
|
|||||||
- [right angle brackets](#right-angle-brackets)
|
- [right angle brackets](#right-angle-brackets)
|
||||||
- [ref-qualified member functions](#ref-qualified-member-functions)
|
- [ref-qualified member functions](#ref-qualified-member-functions)
|
||||||
- [trailing return types](#trailing-return-types)
|
- [trailing return types](#trailing-return-types)
|
||||||
|
- [noexcept specifier](#noexcept-specifier)
|
||||||
|
|
||||||
C++11 includes the following new library features:
|
C++11 includes the following new library features:
|
||||||
- [std::move](#stdmove)
|
- [std::move](#stdmove)
|
||||||
@@ -49,6 +50,7 @@ C++11 includes the following new library features:
|
|||||||
- [std::make_shared](#stdmake_shared)
|
- [std::make_shared](#stdmake_shared)
|
||||||
- [memory model](#memory-model)
|
- [memory model](#memory-model)
|
||||||
- [std::async](#stdasync)
|
- [std::async](#stdasync)
|
||||||
|
- [std::begin/end](#stdbeginend)
|
||||||
|
|
||||||
## C++11 Language Features
|
## C++11 Language Features
|
||||||
|
|
||||||
@@ -128,6 +130,19 @@ static_assert(arity<>::value == 0);
|
|||||||
static_assert(arity<char, short, int>::value == 3);
|
static_assert(arity<char, short, int>::value == 3);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
An interesting use for this is creating an _initializer list_ from a _parameter pack_ in order to iterate over variadic function arguments.
|
||||||
|
```c++
|
||||||
|
template <typename First, typename... Args>
|
||||||
|
auto sum(const First first, const Args... args) -> decltype(first) {
|
||||||
|
const auto values = {first, args...};
|
||||||
|
return std::accumulate(values.begin(), values.end(), First{0});
|
||||||
|
}
|
||||||
|
|
||||||
|
sum(1, 2, 3, 4, 5); // 15
|
||||||
|
sum(1, 2, 3); // 6
|
||||||
|
sum(1.5, 2.0, 3.7); // 7.2
|
||||||
|
```
|
||||||
|
|
||||||
### Initializer lists
|
### Initializer lists
|
||||||
A lightweight array-like container of elements created using a "braced list" syntax. For example, `{ 1, 2, 3 }` creates a sequences of integers, that has type `std::initializer_list<int>`. Useful as a replacement to passing a vector of objects to a function.
|
A lightweight array-like container of elements created using a "braced list" syntax. For example, `{ 1, 2, 3 }` creates a sequences of integers, that has type `std::initializer_list<int>`. Useful as a replacement to passing a vector of objects to a function.
|
||||||
```c++
|
```c++
|
||||||
@@ -243,8 +258,8 @@ add(1, 2.0); // `decltype(x + y)` => `decltype(3.0)` => `double`
|
|||||||
|
|
||||||
See also: `decltype(auto)` (C++14).
|
See also: `decltype(auto)` (C++14).
|
||||||
|
|
||||||
### Template aliases
|
### Type aliases
|
||||||
Semantically similar to using a `typedef` however, template aliases with `using` are easier to read and are compatible with templates.
|
Semantically similar to using a `typedef` however, type aliases with `using` are easier to read and are compatible with templates.
|
||||||
```c++
|
```c++
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using Vec = std::vector<T>;
|
using Vec = std::vector<T>;
|
||||||
@@ -645,6 +660,27 @@ auto add(T a, U b) -> decltype(a + b) {
|
|||||||
```
|
```
|
||||||
In C++14, `decltype(auto)` can be used instead.
|
In C++14, `decltype(auto)` can be used instead.
|
||||||
|
|
||||||
|
### Noexcept specifier
|
||||||
|
The `noexcept` specifier specifies whether a function could throw exceptions. It is an improved version of `throw()`.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
void func1() noexcept; // does not throw
|
||||||
|
void func2() noexcept(true); // does not throw
|
||||||
|
void func3() throw(); // does not throw
|
||||||
|
|
||||||
|
void func4() noexcept(false); // may throw
|
||||||
|
```
|
||||||
|
|
||||||
|
Non-throwing functions are permitted to call potentially-throwing functions. Whenever an exception is thrown and the search for a handler encounters the outermost block of a non-throwing function, the function std::terminate is called.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
extern void f(); // potentially-throwing
|
||||||
|
void g() noexcept {
|
||||||
|
f(); // valid, even if f throws
|
||||||
|
throw 42; // valid, effectively a call to std::terminate
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## C++11 Library Features
|
## C++11 Library Features
|
||||||
|
|
||||||
### std::move
|
### std::move
|
||||||
@@ -861,6 +897,23 @@ auto handle = std::async(std::launch::async, foo); // create an async task
|
|||||||
auto result = handle.get(); // wait for the result
|
auto result = handle.get(); // wait for the result
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### std::begin/end
|
||||||
|
`std::begin` and `std::end` free functions were added to return begin and end iterators of a container generically. These functions also work with raw arrays which do not have begin and end member functions.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
template <typename T>
|
||||||
|
int CountTwos(const T& container) {
|
||||||
|
return std::count_if(std::begin(container), std::end(container), [](int item) {
|
||||||
|
return item == 2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> vec = {2,2,43,435,4543,534};
|
||||||
|
int arr[8] = {2,43,45,435,32,32,32,32};
|
||||||
|
auto a = CountTwos(vec); // 2
|
||||||
|
auto b = CountTwos(arr); // 1
|
||||||
|
```
|
||||||
|
|
||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
* [cppreference](http://en.cppreference.com/w/cpp) - especially useful for finding examples and documentation of new library features.
|
* [cppreference](http://en.cppreference.com/w/cpp) - especially useful for finding examples and documentation of new library features.
|
||||||
* [C++ Rvalue References Explained](http://thbecker.net/articles/rvalue_references/section_01.html) - a great introduction I used to understand rvalue references, perfect forwarding, and move semantics.
|
* [C++ Rvalue References Explained](http://thbecker.net/articles/rvalue_references/section_01.html) - a great introduction I used to understand rvalue references, perfect forwarding, and move semantics.
|
||||||
|
|||||||
12
CPP17.md
12
CPP17.md
@@ -178,6 +178,18 @@ const auto [ x, y ] = origin();
|
|||||||
x; // == 0
|
x; // == 0
|
||||||
y; // == 0
|
y; // == 0
|
||||||
```
|
```
|
||||||
|
```c++
|
||||||
|
std::unordered_map<std::string, int> mapping {
|
||||||
|
{"a", 1},
|
||||||
|
{"b", 2},
|
||||||
|
{"c", 3},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Destructure by reference.
|
||||||
|
for (const auto& [key, value] : mapping) {
|
||||||
|
// Do something with key and value
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Selection statements with initializer
|
### Selection statements with initializer
|
||||||
New versions of the `if` and `switch` statements which simplify common code patterns and help users keep scopes tight.
|
New versions of the `if` and `switch` statements which simplify common code patterns and help users keep scopes tight.
|
||||||
|
|||||||
71
README.md
71
README.md
@@ -62,7 +62,7 @@ C++11 includes the following new language features:
|
|||||||
- [auto](#auto)
|
- [auto](#auto)
|
||||||
- [lambda expressions](#lambda-expressions)
|
- [lambda expressions](#lambda-expressions)
|
||||||
- [decltype](#decltype)
|
- [decltype](#decltype)
|
||||||
- [template aliases](#template-aliases)
|
- [type aliases](#type-aliases)
|
||||||
- [nullptr](#nullptr)
|
- [nullptr](#nullptr)
|
||||||
- [strongly-typed enums](#strongly-typed-enums)
|
- [strongly-typed enums](#strongly-typed-enums)
|
||||||
- [attributes](#attributes)
|
- [attributes](#attributes)
|
||||||
@@ -82,6 +82,7 @@ C++11 includes the following new language features:
|
|||||||
- [right angle brackets](#right-angle-brackets)
|
- [right angle brackets](#right-angle-brackets)
|
||||||
- [ref-qualified member functions](#ref-qualified-member-functions)
|
- [ref-qualified member functions](#ref-qualified-member-functions)
|
||||||
- [trailing return types](#trailing-return-types)
|
- [trailing return types](#trailing-return-types)
|
||||||
|
- [noexcept specifier](#noexcept-specifier)
|
||||||
|
|
||||||
C++11 includes the following new library features:
|
C++11 includes the following new library features:
|
||||||
- [std::move](#stdmove)
|
- [std::move](#stdmove)
|
||||||
@@ -98,6 +99,7 @@ C++11 includes the following new library features:
|
|||||||
- [std::make_shared](#stdmake_shared)
|
- [std::make_shared](#stdmake_shared)
|
||||||
- [memory model](#memory-model)
|
- [memory model](#memory-model)
|
||||||
- [std::async](#stdasync)
|
- [std::async](#stdasync)
|
||||||
|
- [std::begin/end](#stdbeginend)
|
||||||
|
|
||||||
## C++20 Language Features
|
## C++20 Language Features
|
||||||
|
|
||||||
@@ -429,6 +431,18 @@ const auto [ x, y ] = origin();
|
|||||||
x; // == 0
|
x; // == 0
|
||||||
y; // == 0
|
y; // == 0
|
||||||
```
|
```
|
||||||
|
```c++
|
||||||
|
std::unordered_map<std::string, int> mapping {
|
||||||
|
{"a", 1},
|
||||||
|
{"b", 2},
|
||||||
|
{"c", 3},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Destructure by reference.
|
||||||
|
for (const auto& [key, value] : mapping) {
|
||||||
|
// Do something with key and value
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Selection statements with initializer
|
### Selection statements with initializer
|
||||||
New versions of the `if` and `switch` statements which simplify common code patterns and help users keep scopes tight.
|
New versions of the `if` and `switch` statements which simplify common code patterns and help users keep scopes tight.
|
||||||
@@ -939,6 +953,19 @@ static_assert(arity<>::value == 0);
|
|||||||
static_assert(arity<char, short, int>::value == 3);
|
static_assert(arity<char, short, int>::value == 3);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
An interesting use for this is creating an _initializer list_ from a _parameter pack_ in order to iterate over variadic function arguments.
|
||||||
|
```c++
|
||||||
|
template <typename First, typename... Args>
|
||||||
|
auto sum(const First first, const Args... args) -> decltype(first) {
|
||||||
|
const auto values = {first, args...};
|
||||||
|
return std::accumulate(values.begin(), values.end(), First{0});
|
||||||
|
}
|
||||||
|
|
||||||
|
sum(1, 2, 3, 4, 5); // 15
|
||||||
|
sum(1, 2, 3); // 6
|
||||||
|
sum(1.5, 2.0, 3.7); // 7.2
|
||||||
|
```
|
||||||
|
|
||||||
### Initializer lists
|
### Initializer lists
|
||||||
A lightweight array-like container of elements created using a "braced list" syntax. For example, `{ 1, 2, 3 }` creates a sequences of integers, that has type `std::initializer_list<int>`. Useful as a replacement to passing a vector of objects to a function.
|
A lightweight array-like container of elements created using a "braced list" syntax. For example, `{ 1, 2, 3 }` creates a sequences of integers, that has type `std::initializer_list<int>`. Useful as a replacement to passing a vector of objects to a function.
|
||||||
```c++
|
```c++
|
||||||
@@ -1054,8 +1081,8 @@ add(1, 2.0); // `decltype(x + y)` => `decltype(3.0)` => `double`
|
|||||||
|
|
||||||
See also: [`decltype(auto)`](#decltypeauto).
|
See also: [`decltype(auto)`](#decltypeauto).
|
||||||
|
|
||||||
### Template aliases
|
### Type aliases
|
||||||
Semantically similar to using a `typedef` however, template aliases with `using` are easier to read and are compatible with templates.
|
Semantically similar to using a `typedef` however, type aliases with `using` are easier to read and are compatible with templates.
|
||||||
```c++
|
```c++
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using Vec = std::vector<T>;
|
using Vec = std::vector<T>;
|
||||||
@@ -1457,6 +1484,27 @@ auto add(T a, U b) -> decltype(a + b) {
|
|||||||
```
|
```
|
||||||
In C++14, [decltype(auto)](#decltypeauto) can be used instead.
|
In C++14, [decltype(auto)](#decltypeauto) can be used instead.
|
||||||
|
|
||||||
|
### Noexcept specifier
|
||||||
|
The `noexcept` specifier specifies whether a function could throw exceptions. It is an improved version of `throw()`.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
void func1() noexcept; // does not throw
|
||||||
|
void func2() noexcept(true); // does not throw
|
||||||
|
void func3() throw(); // does not throw
|
||||||
|
|
||||||
|
void func4() noexcept(false); // may throw
|
||||||
|
```
|
||||||
|
|
||||||
|
Non-throwing functions are permitted to call potentially-throwing functions. Whenever an exception is thrown and the search for a handler encounters the outermost block of a non-throwing function, the function std::terminate is called.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
extern void f(); // potentially-throwing
|
||||||
|
void g() noexcept {
|
||||||
|
f(); // valid, even if f throws
|
||||||
|
throw 42; // valid, effectively a call to std::terminate
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## C++11 Library Features
|
## C++11 Library Features
|
||||||
|
|
||||||
### std::move
|
### std::move
|
||||||
@@ -1673,6 +1721,23 @@ auto handle = std::async(std::launch::async, foo); // create an async task
|
|||||||
auto result = handle.get(); // wait for the result
|
auto result = handle.get(); // wait for the result
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### std::begin/end
|
||||||
|
`std::begin` and `std::end` free functions were added to return begin and end iterators of a container generically. These functions also work with raw arrays which do not have begin and end member functions.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
template <typename T>
|
||||||
|
int CountTwos(const T& container) {
|
||||||
|
return std::count_if(std::begin(container), std::end(container), [](int item) {
|
||||||
|
return item == 2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> vec = {2,2,43,435,4543,534};
|
||||||
|
int arr[8] = {2,43,45,435,32,32,32,32};
|
||||||
|
auto a = CountTwos(vec); // 2
|
||||||
|
auto b = CountTwos(arr); // 1
|
||||||
|
```
|
||||||
|
|
||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
* [cppreference](http://en.cppreference.com/w/cpp) - especially useful for finding examples and documentation of new library features.
|
* [cppreference](http://en.cppreference.com/w/cpp) - especially useful for finding examples and documentation of new library features.
|
||||||
* [C++ Rvalue References Explained](http://thbecker.net/articles/rvalue_references/section_01.html) - a great introduction I used to understand rvalue references, perfect forwarding, and move semantics.
|
* [C++ Rvalue References Explained](http://thbecker.net/articles/rvalue_references/section_01.html) - a great introduction I used to understand rvalue references, perfect forwarding, and move semantics.
|
||||||
|
|||||||
Reference in New Issue
Block a user