244 lines
6.4 KiB
Markdown
244 lines
6.4 KiB
Markdown
## Nested namespace definitions
|
|
<!-- .slide: data-background="#ccc" -->
|
|
|
|
You can nest namespaces like this:
|
|
<!-- .element: class="fragment fade-in" -->
|
|
|
|
```c++
|
|
namespace A::B::C {
|
|
...
|
|
}
|
|
```
|
|
<!-- .element: class="fragment fade-in" -->
|
|
Instead of this:
|
|
<!-- .element: class="fragment fade-in" -->
|
|
|
|
```c++
|
|
namespace A {
|
|
namespace B {
|
|
namespace C {
|
|
...
|
|
}
|
|
}
|
|
}
|
|
```
|
|
<!-- .element: class="fragment fade-in" -->
|
|
___
|
|
<!-- .slide: data-background="#ccc" --><!-- .slide: data-background="#ccc" -->
|
|
|
|
## Class template argument deduction
|
|
|
|
From C++17 class template arguments can be deduced automatically. Automatic template argument deduction was available earlier only for template functions.
|
|
|
|
```c++
|
|
std::pair p(1, 'x'); // C++17: OK, C++14: error: missing.
|
|
// std::pair<int, char>
|
|
std::pair<int, std::string> p(1, "x"); // C++14: OK
|
|
// std::pair<int, std::string>
|
|
auto p2 = std::make_pair(1, "x"); // C++17: OK, C++14: OK (but not string!)
|
|
// std::pair<int, const char*>
|
|
std::pair p3(1, "x"); // C++17: OK (but not string!), C++14 error
|
|
```
|
|
|
|
___
|
|
<!-- .slide: data-background="#ccc" --><!-- .slide: data-background="#ccc" -->
|
|
|
|
## Selection statements with initializer (1)
|
|
|
|
New versions of the `if` and `switch` statements for C++:
|
|
<!-- .element: class="fragment fade-in" -->
|
|
|
|
### `if (init; condition)`
|
|
<!-- .element: class="fragment fade-in" -->
|
|
|
|
```cpp
|
|
status_code foo() { // C++14
|
|
{ //variable c scope
|
|
status_code c = bar();
|
|
if (c != SUCCESS) {
|
|
return c;
|
|
}
|
|
}
|
|
// ...
|
|
}
|
|
```
|
|
<!-- .element: class="fragment fade-in" -->
|
|
|
|
```cpp
|
|
status_code foo() { // C++17
|
|
if (status_code c = bar(); c != SUCCESS) {
|
|
return c;
|
|
}
|
|
// ...
|
|
}
|
|
```
|
|
<!-- .element: class="fragment fade-in" -->
|
|
<!-- .slide: style="font-size: 0.8em" -->
|
|
___
|
|
<!-- .slide: data-background="#ccc" --><!-- .slide: data-background="#ccc" -->
|
|
|
|
## Selection statements with initializer (2)
|
|
|
|
### `switch (init; condition)`
|
|
<!-- .element: class="fragment fade-in" -->
|
|
|
|
```C++
|
|
class Foo {
|
|
public:
|
|
enum class ErrorCode {
|
|
Ok,
|
|
Bad,
|
|
VeryBad
|
|
};
|
|
|
|
ErrorCode doSth() {}
|
|
}
|
|
|
|
int main() {
|
|
switch (Foo foo ; const auto err = foo.doSth()) {
|
|
case ErrorCode::Ok:
|
|
break;
|
|
case ErrorCode::Bad:
|
|
break;
|
|
case ErrorCode::VeryBad:
|
|
break;
|
|
}
|
|
}
|
|
```
|
|
<!-- .slide: style="font-size: 0.85em" -->
|
|
<!-- .element: class="fragment fade-in" -->
|
|
___
|
|
<!-- .slide: data-background="#ccc" --><!-- .slide: data-background="#ccc" -->
|
|
|
|
## Selection statements with initializer (3)
|
|
|
|
```C++
|
|
class ThreadSafeQueue {
|
|
public:
|
|
std::optional<int> try_pop() {
|
|
int val = 0;
|
|
// Lock guard is visible inside if-else
|
|
if (std::lock_guard lock(m_) ; queue_.empty()) {
|
|
return {};
|
|
} else {
|
|
val = queue_.front();
|
|
queue_.pop();
|
|
}
|
|
|
|
// Here mutex is no longer locked
|
|
logger << "pop value from queue";
|
|
return val;
|
|
}
|
|
|
|
private:
|
|
std::queue<int> queue_;
|
|
std::mutex m_;
|
|
};
|
|
```
|
|
<!-- .element: class="fragment fade-in" -->
|
|
<!-- .slide: style="font-size: 0.92em" -->
|
|
|
|
___
|
|
<!-- .slide: data-background="#ccc" --><!-- .slide: data-background="#ccc" -->
|
|
|
|
## Hiding variable inside <code>if-else</code> statement (2)
|
|
|
|
We can avoid assigning iterators and then comapre it in `if` statement. Now we can write it faster
|
|
|
|
```C++
|
|
int main() {
|
|
std::vector<int> vec;
|
|
|
|
if (const auto it = std::find(std::cbegin(vec), std::cend(vec), 10) ; it != std::cend(vec)) {
|
|
// *it* is visible here
|
|
} else {
|
|
// and here
|
|
}
|
|
// but not here
|
|
|
|
std::map<std::string, int>
|
|
if (const auto it = map.find("Ala") ; it != std::cend(map)) {
|
|
// ...
|
|
} else {
|
|
// ...
|
|
}
|
|
}
|
|
```
|
|
<!-- .slide: style="font-size: 0.79em" -->
|
|
___
|
|
<!-- .slide: data-background="#ccc" --><!-- .slide: data-background="#ccc" -->
|
|
|
|
## Unified initialization
|
|
|
|
* <!-- .element: class="fragment fade-in" --> C++11 introduce <code>{}</code> for initialization
|
|
* <!-- .element: class="fragment fade-in" --> C++17 fixed some problems with <code>{}</code> and unified it.
|
|
|
|
___
|
|
<!-- .slide: data-background="#ccc" --><!-- .slide: data-background="#ccc" -->
|
|
|
|
## Unified initialization C++11
|
|
|
|
* Guess output (compiler 4.7.4 with C++11 flag)
|
|
|
|
<pre><code class="cpp" data-trim data-line-numbers data-noescape>
|
|
auto a {1}; <span class="fragment">//std::initializer_list<int></span>
|
|
auto b = {1}; <span class="fragment">//std::initializer_list<int></span>
|
|
auto c {1, 2}; <span class="fragment">//std::initializer_list<int></span>
|
|
auto d = {1, 2}; <span class="fragment">//std::initializer_list<int></span>
|
|
auto e = {1, 2, 3.f}; <span class="fragment">//Not compile </span>
|
|
auto f {1, 2, 3.f} <span class="fragment">//Not compile </span>
|
|
</code></pre>
|
|
|
|
___
|
|
<!-- .slide: data-background="#ccc" --><!-- .slide: data-background="#ccc" -->
|
|
|
|
## Unified initialization C++17
|
|
|
|
* Guess output (compiler 8.4 with C++17 flag)
|
|
|
|
<pre><code class="cpp" data-trim data-line-numbers data-noescape>
|
|
auto a {1}; <span class="fragment">//int </span>
|
|
auto b = {1}; <span class="fragment">//std::initializer_list<int></span>
|
|
auto c {1, 2}; <span class="fragment">//Not compile (mising =) </span>
|
|
auto d = {1, 2}; <span class="fragment">//std::initializer_list<int></span>
|
|
auto e = {1, 2, 3.f}; <span class="fragment">//Not compile </span>
|
|
auto f {1, 2, 3.f} <span class="fragment">//Not compile </span>
|
|
</code></pre>
|
|
|
|
___
|
|
<!-- .slide: data-background="#ccc" --><!-- .slide: data-background="#ccc" -->
|
|
|
|
## Structural biding
|
|
|
|
* <!-- .element: class="fragment fade-in" --> Unpack strucures, classes, tuples, pairs etc...
|
|
|
|
```C++
|
|
struct Foo{};
|
|
|
|
std::tuple<int, std::string, Foo> getTuple() {
|
|
return {5, "Ala has a cat", Foo{}};
|
|
}
|
|
|
|
struct Bar {
|
|
std::string str_;
|
|
double val_;
|
|
char c_;
|
|
std::vector<int> vec_;
|
|
};
|
|
|
|
int main() {
|
|
const auto& [id, topic, foo] = getTuple();
|
|
|
|
std::vector<Bar> bar;
|
|
for (const auto& [name, value, sign, vec] : bar) {
|
|
// ...
|
|
}
|
|
|
|
std::map<int, std::string> map;
|
|
for (const auto& [key, value] : map) {
|
|
// ..
|
|
}
|
|
};
|
|
```
|
|
<!-- .element: class="fragment fade-in" -->
|
|
<!-- .slide: style="font-size: 0.70em" -->
|