C++ 17
Karta Features of c++17 (link)Karta Features of c++ 20(link)
When you see an article about new C++ features, most of the time you’ll see a description of major elements. Looking at C++17, there are a lot of posts (including articles from this blog) about structured bindings, filesystem, parallel algorithms, if constexpr, std::optional, std::variant… and other prominent C++17 additions.
In this article, I’ll show you 17 smaller C++17 things that will improve your code.
The Language
1. Dynamic Memory Allocation for Over-Aligned Data
2. Inline Variables
3. __has_include Preprocessor Expression
The Standard Library
4. Variable Templates for Traits
5. Logical Operation Metafunctions
6. std::void_t Transformation Trait
7. std::from_chars
8. Splicing for maps and sets
9. try_emplace() Method
10. insert_or_assign() Method
11. Return Type of Emplace Methods
12. Sampling Algorithms
13. gcd(), lcm() and clamp()
14. Shared Pointers and Arrays
15. std::scoped_lock
Removed Elements
16. Removing auto_ptr
17. Removing Old functional Stuff
Std::optional dodaje nam możliwość zwrócenia stanu "pusty" - nullopt przy różnych typach.
Stan "pusty" - nullopt, może być sprawdzany warunkiem IF jak w przykładzie:
Przykład działania optional
Można również zwrócić taki stan za pomocą return std::nullopt jak w poniższym przykładzie:
Drugi przykład działania option
Std::variant może przyjmować dowolne, wcześniej określone typy, slbo stan pusty (tu realizowany za pomocą std::monostate )
Patrz na przykład zastosowania std::variant jako nowoczesnej maszyny stanów.
LINK
Pozwala wybierać gałęzie na poziomie kompilowania na podstawie warunków constexpr (wyrażenie stałe).
Uproszcza kod Templatów, szczególnie jeśli używane SFINAE
(Niepowodzenie podstawienia nie jest błędem (SFINAE) odnosi się do sytuacji w C ++, w której nieprawidłowe zastąpienie parametrów szablonu samo w sobie nie jest błędem)
wiecej 303 i 58 (książka Filipek)
In this article, I’ll show you 17 smaller C++17 things that will improve your code.
The Language
1. Dynamic Memory Allocation for Over-Aligned Data
2. Inline Variables
3. __has_include Preprocessor Expression
The Standard Library
4. Variable Templates for Traits
5. Logical Operation Metafunctions
6. std::void_t Transformation Trait
7. std::from_chars
8. Splicing for maps and sets
9. try_emplace() Method
10. insert_or_assign() Method
11. Return Type of Emplace Methods
12. Sampling Algorithms
13. gcd(), lcm() and clamp()
14. Shared Pointers and Arrays
15. std::scoped_lock
Removed Elements
16. Removing auto_ptr
17. Removing Old functional Stuff
.........................................
std::optional
Std::optional dodaje nam możliwość zwrócenia stanu "pusty" - nullopt przy różnych typach.
Stan "pusty" - nullopt, może być sprawdzany warunkiem IF jak w przykładzie:
Przykład działania optional
#include <iostream> #include <vector> #include <optional> void Process(int) { }; int main() { std::vector<int> vec { 1, 2, 3, 4, 5, 6, 7, 101, 8, 9 }; std::optional<int> largerThan100; for (auto& elem : vec) { Process(elem); if (elem > 100 && !largerThan100) largerThan100 = elem; } // later on selected elements... if (largerThan100) std::cout << *largerThan100; }
Można również zwrócić taki stan za pomocą return std::nullopt jak w poniższym przykładzie:
Drugi przykład działania option
#include <iostream> #include <vector> #include <optional> template <typename TContainer> std::optional<typename TContainer::value_type> FindVal(const TContainer& container, const typename TContainer::value_type& key) { auto it = std::find(std::begin(container), std::end(container), key); if (it != std::end(container)) return *it; return std::nullopt; // or std::nullopt } int main() { std::vector<int> v{ 1, 2, 3, 4, 5, 6, 7 }; auto i = FindVal(v, 1); if (i) std::cout << *i; }
std::variant
Std::variant może przyjmować dowolne, wcześniej określone typy, slbo stan pusty (tu realizowany za pomocą std::monostate )
#include <iostream> #include <vector> #include <optional> #include <variant> #include <cmath> // aX^2 + bX + c using TRoots = std::variant<std::monostate, double, std::pair<double, double>>; TRoots FindRoots(double a, double b, double c) { const auto delta = b*b-4*a*c; if (delta > 0.0) { auto p = sqrt(delta); double x1 = (-b + p)/(2*a); double x2 = (-b - p)/(2*a); return std::pair(x1, x2); } else if (delta == 0.0) { return -b/(2*a); } return std::monostate(); } void ShowRoots(const TRoots& roots) { switch (roots.index()) { case 0: std::cout << "no roots!\n"; break; case 1: std::cout << std::get<1>(roots) << '\n'; break; case 2: std::cout << std::get<2>(roots).first << ", " << std::get<2>(roots).second << '\n'; break; } } int main() { ShowRoots(FindRoots(1, -3, 4)); ShowRoots(FindRoots(-4, 12, -9)); ShowRoots(FindRoots(2, -11, 5)); }
Patrz na przykład zastosowania std::variant jako nowoczesnej maszyny stanów.
LINK
if constexpr
Pozwala wybierać gałęzie na poziomie kompilowania na podstawie warunków constexpr (wyrażenie stałe).
template <typename T> auto get_value(T t) { if constexpr (std::is_pointer_v<T>) return *t; else return t; }
Uproszcza kod Templatów, szczególnie jeśli używane SFINAE
(Niepowodzenie podstawienia nie jest błędem (SFINAE) odnosi się do sytuacji w C ++, w której nieprawidłowe zastąpienie parametrów szablonu samo w sobie nie jest błędem)
wiecej 303 i 58 (książka Filipek)