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)
|
||||
- [lambda expressions](#lambda-expressions)
|
||||
- [decltype](#decltype)
|
||||
- [template aliases](#template-aliases)
|
||||
- [type aliases](#type-aliases)
|
||||
- [nullptr](#nullptr)
|
||||
- [strongly-typed enums](#strongly-typed-enums)
|
||||
- [attributes](#attributes)
|
||||
@@ -33,6 +33,7 @@ C++11 includes the following new language features:
|
||||
- [right angle brackets](#right-angle-brackets)
|
||||
- [ref-qualified member functions](#ref-qualified-member-functions)
|
||||
- [trailing return types](#trailing-return-types)
|
||||
- [noexcept specifier](#noexcept-specifier)
|
||||
|
||||
C++11 includes the following new library features:
|
||||
- [std::move](#stdmove)
|
||||
@@ -49,6 +50,7 @@ C++11 includes the following new library features:
|
||||
- [std::make_shared](#stdmake_shared)
|
||||
- [memory model](#memory-model)
|
||||
- [std::async](#stdasync)
|
||||
- [std::begin/end](#stdbeginend)
|
||||
|
||||
## C++11 Language Features
|
||||
|
||||
@@ -128,6 +130,19 @@ static_assert(arity<>::value == 0);
|
||||
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
|
||||
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++
|
||||
@@ -243,8 +258,8 @@ add(1, 2.0); // `decltype(x + y)` => `decltype(3.0)` => `double`
|
||||
|
||||
See also: `decltype(auto)` (C++14).
|
||||
|
||||
### Template aliases
|
||||
Semantically similar to using a `typedef` however, template aliases with `using` are easier to read and are compatible with templates.
|
||||
### Type aliases
|
||||
Semantically similar to using a `typedef` however, type aliases with `using` are easier to read and are compatible with templates.
|
||||
```c++
|
||||
template <typename 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.
|
||||
|
||||
### 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
|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||
### 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
|
||||
* [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.
|
||||
|
||||
12
CPP17.md
12
CPP17.md
@@ -178,6 +178,18 @@ const auto [ x, y ] = origin();
|
||||
x; // == 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
|
||||
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)
|
||||
- [lambda expressions](#lambda-expressions)
|
||||
- [decltype](#decltype)
|
||||
- [template aliases](#template-aliases)
|
||||
- [type aliases](#type-aliases)
|
||||
- [nullptr](#nullptr)
|
||||
- [strongly-typed enums](#strongly-typed-enums)
|
||||
- [attributes](#attributes)
|
||||
@@ -82,6 +82,7 @@ C++11 includes the following new language features:
|
||||
- [right angle brackets](#right-angle-brackets)
|
||||
- [ref-qualified member functions](#ref-qualified-member-functions)
|
||||
- [trailing return types](#trailing-return-types)
|
||||
- [noexcept specifier](#noexcept-specifier)
|
||||
|
||||
C++11 includes the following new library features:
|
||||
- [std::move](#stdmove)
|
||||
@@ -98,6 +99,7 @@ C++11 includes the following new library features:
|
||||
- [std::make_shared](#stdmake_shared)
|
||||
- [memory model](#memory-model)
|
||||
- [std::async](#stdasync)
|
||||
- [std::begin/end](#stdbeginend)
|
||||
|
||||
## C++20 Language Features
|
||||
|
||||
@@ -429,6 +431,18 @@ const auto [ x, y ] = origin();
|
||||
x; // == 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
|
||||
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);
|
||||
```
|
||||
|
||||
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
|
||||
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++
|
||||
@@ -1054,8 +1081,8 @@ add(1, 2.0); // `decltype(x + y)` => `decltype(3.0)` => `double`
|
||||
|
||||
See also: [`decltype(auto)`](#decltypeauto).
|
||||
|
||||
### Template aliases
|
||||
Semantically similar to using a `typedef` however, template aliases with `using` are easier to read and are compatible with templates.
|
||||
### Type aliases
|
||||
Semantically similar to using a `typedef` however, type aliases with `using` are easier to read and are compatible with templates.
|
||||
```c++
|
||||
template <typename 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.
|
||||
|
||||
### 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
|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||
### 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
|
||||
* [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.
|
||||
|
||||
Reference in New Issue
Block a user