mirror of
https://github.com/AnthonyCalandra/modern-cpp-features.git
synced 2025-12-18 18:44:35 +03:00
Cleanup; consistent formatting.
This commit is contained in:
33
CPP11.md
33
CPP11.md
@@ -245,7 +245,7 @@ Semantically similar to using a `typedef` however, template aliases with `using`
|
|||||||
```c++
|
```c++
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using Vec = std::vector<T>;
|
using Vec = std::vector<T>;
|
||||||
Vec<int> v{}; // std::vector<int>
|
Vec<int> v; // std::vector<int>
|
||||||
|
|
||||||
using String = std::string;
|
using String = std::string;
|
||||||
String s {"foo"};
|
String s {"foo"};
|
||||||
@@ -327,7 +327,7 @@ struct Foo {
|
|||||||
Foo() : Foo(0) {}
|
Foo() : Foo(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
Foo foo{};
|
Foo foo;
|
||||||
foo.foo; // == 0
|
foo.foo; // == 0
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -403,14 +403,14 @@ struct A {
|
|||||||
A(int x) : x(x) {}
|
A(int x) : x(x) {}
|
||||||
int x {1};
|
int x {1};
|
||||||
};
|
};
|
||||||
A a{}; // a.x == 1
|
A a; // a.x == 1
|
||||||
A a2 {123}; // a.x == 123
|
A a2 {123}; // a.x == 123
|
||||||
```
|
```
|
||||||
|
|
||||||
With inheritance:
|
With inheritance:
|
||||||
```c++
|
```c++
|
||||||
struct B {
|
struct B {
|
||||||
B() : x(1);
|
B() : x(1) {}
|
||||||
int x;
|
int x;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ struct C : B {
|
|||||||
C() = default;
|
C() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
C c{}; // c.x == 1
|
C c; // c.x == 1
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deleted functions
|
### Deleted functions
|
||||||
@@ -530,11 +530,11 @@ struct B {
|
|||||||
explicit operator bool() const { return true; }
|
explicit operator bool() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
A a{};
|
A a;
|
||||||
if (a); // OK calls A::operator bool()
|
if (a); // OK calls A::operator bool()
|
||||||
bool ba = a; // OK copy-initialization selects A::operator bool()
|
bool ba = a; // OK copy-initialization selects A::operator bool()
|
||||||
|
|
||||||
B b{};
|
B b;
|
||||||
if (b); // OK calls B::operator bool()
|
if (b); // OK calls B::operator bool()
|
||||||
bool bb = b; // error copy-initialization does not consider B::operator bool()
|
bool bb = b; // error copy-initialization does not consider B::operator bool()
|
||||||
```
|
```
|
||||||
@@ -574,7 +574,6 @@ class Human {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Right angle Brackets
|
### Right angle Brackets
|
||||||
C++11 is now able to infer when a series of right angle brackets is used as an operator or as a closing statement of typedef, without having to add whitespace.
|
C++11 is now able to infer when a series of right angle brackets is used as an operator or as a closing statement of typedef, without having to add whitespace.
|
||||||
|
|
||||||
@@ -598,7 +597,7 @@ typename remove_reference<T>::type&& move(T&& arg) {
|
|||||||
|
|
||||||
Transferring `std::unique_ptr`s:
|
Transferring `std::unique_ptr`s:
|
||||||
```c++
|
```c++
|
||||||
std::unique_ptr<int> p1{ new int };
|
std::unique_ptr<int> p1 {new int{0}};
|
||||||
std::unique_ptr<int> p2 = p1; // error -- cannot copy unique pointers
|
std::unique_ptr<int> p2 = p1; // error -- cannot copy unique pointers
|
||||||
std::unique_ptr<int> p3 = std::move(p1); // move `p1` into `p3`
|
std::unique_ptr<int> p3 = std::move(p1); // move `p1` into `p3`
|
||||||
// now unsafe to dereference object held by `p1`
|
// now unsafe to dereference object held by `p1`
|
||||||
@@ -629,7 +628,7 @@ A wrapper(T&& arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wrapper(A{}); // moved
|
wrapper(A{}); // moved
|
||||||
A a{};
|
A a;
|
||||||
wrapper(a); // copied
|
wrapper(a); // copied
|
||||||
wrapper(std::move(a)); // moved
|
wrapper(std::move(a)); // moved
|
||||||
```
|
```
|
||||||
@@ -647,8 +646,9 @@ threadsVector.emplace_back([]() {
|
|||||||
// Lambda function that will be invoked
|
// Lambda function that will be invoked
|
||||||
});
|
});
|
||||||
threadsVector.emplace_back(foo, true); // thread will run foo(true)
|
threadsVector.emplace_back(foo, true); // thread will run foo(true)
|
||||||
for (auto& thread : threadsVector)
|
for (auto& thread : threadsVector) {
|
||||||
thread.join(); // Wait for threads to finish
|
thread.join(); // Wait for threads to finish
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### std::to_string
|
### std::to_string
|
||||||
@@ -672,7 +672,9 @@ C++11 introduces new smart(er) pointers: `std::unique_ptr`, `std::shared_ptr`, `
|
|||||||
`std::unique_ptr` is a non-copyable, movable smart pointer that properly manages arrays and STL containers. **Note: Prefer using the `std::make_X` helper functions as opposed to using constructors. See the sections for [std::make_unique](#stdmake_unique) and [std::make_shared](#stdmake_shared).**
|
`std::unique_ptr` is a non-copyable, movable smart pointer that properly manages arrays and STL containers. **Note: Prefer using the `std::make_X` helper functions as opposed to using constructors. See the sections for [std::make_unique](#stdmake_unique) and [std::make_shared](#stdmake_shared).**
|
||||||
```c++
|
```c++
|
||||||
std::unique_ptr<Foo> p1 { new Foo{} }; // `p1` owns `Foo`
|
std::unique_ptr<Foo> p1 { new Foo{} }; // `p1` owns `Foo`
|
||||||
if (p1) p1->bar();
|
if (p1) {
|
||||||
|
p1->bar();
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<Foo> p2 {std::move(p1)}; // Now `p2` owns `Foo`
|
std::unique_ptr<Foo> p2 {std::move(p1)}; // Now `p2` owns `Foo`
|
||||||
@@ -681,7 +683,9 @@ if (p1) p1->bar();
|
|||||||
p1 = std::move(p2); // Ownership returns to `p1` -- `p2` gets destroyed
|
p1 = std::move(p2); // Ownership returns to `p1` -- `p2` gets destroyed
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p1) p1->bar();
|
if (p1) {
|
||||||
|
p1->bar();
|
||||||
|
}
|
||||||
// `Foo` instance is destroyed when `p1` goes out of scope
|
// `Foo` instance is destroyed when `p1` goes out of scope
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -715,7 +719,6 @@ start = std::chrono::steady_clock::now();
|
|||||||
end = std::chrono::steady_clock::now();
|
end = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
std::chrono::duration<double> elapsed_seconds = end - start;
|
std::chrono::duration<double> elapsed_seconds = end - start;
|
||||||
|
|
||||||
elapsed_seconds.count(); // t number of seconds, represented as a `double`
|
elapsed_seconds.count(); // t number of seconds, represented as a `double`
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -785,7 +788,7 @@ The first parameter is the policy which can be:
|
|||||||
1. `std::launch::async` Run the callable object on a new thread.
|
1. `std::launch::async` Run the callable object on a new thread.
|
||||||
1. `std::launch::deferred` Perform lazy evaluation on the current thread.
|
1. `std::launch::deferred` Perform lazy evaluation on the current thread.
|
||||||
|
|
||||||
```
|
```c++
|
||||||
int foo() {
|
int foo() {
|
||||||
/* Do something here, then return the result. */
|
/* Do something here, then return the result. */
|
||||||
return 1000;
|
return 1000;
|
||||||
|
|||||||
33
README.md
33
README.md
@@ -831,7 +831,7 @@ Semantically similar to using a `typedef` however, template aliases with `using`
|
|||||||
```c++
|
```c++
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using Vec = std::vector<T>;
|
using Vec = std::vector<T>;
|
||||||
Vec<int> v{}; // std::vector<int>
|
Vec<int> v; // std::vector<int>
|
||||||
|
|
||||||
using String = std::string;
|
using String = std::string;
|
||||||
String s {"foo"};
|
String s {"foo"};
|
||||||
@@ -913,7 +913,7 @@ struct Foo {
|
|||||||
Foo() : Foo(0) {}
|
Foo() : Foo(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
Foo foo{};
|
Foo foo;
|
||||||
foo.foo; // == 0
|
foo.foo; // == 0
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -989,14 +989,14 @@ struct A {
|
|||||||
A(int x) : x(x) {}
|
A(int x) : x(x) {}
|
||||||
int x {1};
|
int x {1};
|
||||||
};
|
};
|
||||||
A a{}; // a.x == 1
|
A a; // a.x == 1
|
||||||
A a2 {123}; // a.x == 123
|
A a2 {123}; // a.x == 123
|
||||||
```
|
```
|
||||||
|
|
||||||
With inheritance:
|
With inheritance:
|
||||||
```c++
|
```c++
|
||||||
struct B {
|
struct B {
|
||||||
B() : x(1);
|
B() : x(1) {}
|
||||||
int x;
|
int x;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1005,7 +1005,7 @@ struct C : B {
|
|||||||
C() = default;
|
C() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
C c{}; // c.x == 1
|
C c; // c.x == 1
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deleted functions
|
### Deleted functions
|
||||||
@@ -1116,11 +1116,11 @@ struct B {
|
|||||||
explicit operator bool() const { return true; }
|
explicit operator bool() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
A a{};
|
A a;
|
||||||
if (a); // OK calls A::operator bool()
|
if (a); // OK calls A::operator bool()
|
||||||
bool ba = a; // OK copy-initialization selects A::operator bool()
|
bool ba = a; // OK copy-initialization selects A::operator bool()
|
||||||
|
|
||||||
B b{};
|
B b;
|
||||||
if (b); // OK calls B::operator bool()
|
if (b); // OK calls B::operator bool()
|
||||||
bool bb = b; // error copy-initialization does not consider B::operator bool()
|
bool bb = b; // error copy-initialization does not consider B::operator bool()
|
||||||
```
|
```
|
||||||
@@ -1160,7 +1160,6 @@ class Human {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Right angle Brackets
|
### Right angle Brackets
|
||||||
C++11 is now able to infer when a series of right angle brackets is used as an operator or as a closing statement of typedef, without having to add whitespace.
|
C++11 is now able to infer when a series of right angle brackets is used as an operator or as a closing statement of typedef, without having to add whitespace.
|
||||||
|
|
||||||
@@ -1184,7 +1183,7 @@ typename remove_reference<T>::type&& move(T&& arg) {
|
|||||||
|
|
||||||
Transferring `std::unique_ptr`s:
|
Transferring `std::unique_ptr`s:
|
||||||
```c++
|
```c++
|
||||||
std::unique_ptr<int> p1{ new int };
|
std::unique_ptr<int> p1 {new int{0}};
|
||||||
std::unique_ptr<int> p2 = p1; // error -- cannot copy unique pointers
|
std::unique_ptr<int> p2 = p1; // error -- cannot copy unique pointers
|
||||||
std::unique_ptr<int> p3 = std::move(p1); // move `p1` into `p3`
|
std::unique_ptr<int> p3 = std::move(p1); // move `p1` into `p3`
|
||||||
// now unsafe to dereference object held by `p1`
|
// now unsafe to dereference object held by `p1`
|
||||||
@@ -1215,7 +1214,7 @@ A wrapper(T&& arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wrapper(A{}); // moved
|
wrapper(A{}); // moved
|
||||||
A a{};
|
A a;
|
||||||
wrapper(a); // copied
|
wrapper(a); // copied
|
||||||
wrapper(std::move(a)); // moved
|
wrapper(std::move(a)); // moved
|
||||||
```
|
```
|
||||||
@@ -1233,8 +1232,9 @@ threadsVector.emplace_back([]() {
|
|||||||
// Lambda function that will be invoked
|
// Lambda function that will be invoked
|
||||||
});
|
});
|
||||||
threadsVector.emplace_back(foo, true); // thread will run foo(true)
|
threadsVector.emplace_back(foo, true); // thread will run foo(true)
|
||||||
for (auto& thread : threadsVector)
|
for (auto& thread : threadsVector) {
|
||||||
thread.join(); // Wait for threads to finish
|
thread.join(); // Wait for threads to finish
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### std::to_string
|
### std::to_string
|
||||||
@@ -1258,7 +1258,9 @@ C++11 introduces new smart(er) pointers: `std::unique_ptr`, `std::shared_ptr`, `
|
|||||||
`std::unique_ptr` is a non-copyable, movable smart pointer that properly manages arrays and STL containers. **Note: Prefer using the `std::make_X` helper functions as opposed to using constructors. See the sections for [std::make_unique](#stdmake_unique) and [std::make_shared](#stdmake_shared).**
|
`std::unique_ptr` is a non-copyable, movable smart pointer that properly manages arrays and STL containers. **Note: Prefer using the `std::make_X` helper functions as opposed to using constructors. See the sections for [std::make_unique](#stdmake_unique) and [std::make_shared](#stdmake_shared).**
|
||||||
```c++
|
```c++
|
||||||
std::unique_ptr<Foo> p1 {new Foo{}}; // `p1` owns `Foo`
|
std::unique_ptr<Foo> p1 {new Foo{}}; // `p1` owns `Foo`
|
||||||
if (p1) p1->bar();
|
if (p1) {
|
||||||
|
p1->bar();
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<Foo> p2 {std::move(p1)}; // Now `p2` owns `Foo`
|
std::unique_ptr<Foo> p2 {std::move(p1)}; // Now `p2` owns `Foo`
|
||||||
@@ -1267,7 +1269,9 @@ if (p1) p1->bar();
|
|||||||
p1 = std::move(p2); // Ownership returns to `p1` -- `p2` gets destroyed
|
p1 = std::move(p2); // Ownership returns to `p1` -- `p2` gets destroyed
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p1) p1->bar();
|
if (p1) {
|
||||||
|
p1->bar();
|
||||||
|
}
|
||||||
// `Foo` instance is destroyed when `p1` goes out of scope
|
// `Foo` instance is destroyed when `p1` goes out of scope
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1301,7 +1305,6 @@ start = std::chrono::steady_clock::now();
|
|||||||
end = std::chrono::steady_clock::now();
|
end = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
std::chrono::duration<double> elapsed_seconds = end - start;
|
std::chrono::duration<double> elapsed_seconds = end - start;
|
||||||
|
|
||||||
elapsed_seconds.count(); // t number of seconds, represented as a `double`
|
elapsed_seconds.count(); // t number of seconds, represented as a `double`
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1371,7 +1374,7 @@ The first parameter is the policy which can be:
|
|||||||
1. `std::launch::async` Run the callable object on a new thread.
|
1. `std::launch::async` Run the callable object on a new thread.
|
||||||
1. `std::launch::deferred` Perform lazy evaluation on the current thread.
|
1. `std::launch::deferred` Perform lazy evaluation on the current thread.
|
||||||
|
|
||||||
```
|
```c++
|
||||||
int foo() {
|
int foo() {
|
||||||
/* Do something here, then return the result. */
|
/* Do something here, then return the result. */
|
||||||
return 1000;
|
return 1000;
|
||||||
|
|||||||
Reference in New Issue
Block a user