Ostatnio w ramach „się odstresowywania” czytam sobie o zmianach w standardzie c++17 i c++20 (wielkie dzięki Bartkowi Filipkowi za jego bloga). Dużo tego, ale zmiany są ogromne i dzisiejszy C++ jest po prostu fascynujący. Nawet nie komentuje poniższego kodu. Wklejam tu dla samego siebie i powiem tylko, że jak g++/clang++ będą z c++20 zgodne, to ja już nie chcę nic więcej. Może jeszcze tylko ogarnięcie parallelstl. Intel-tbb działa pięknie. Tylko jeden cytat apropos:
„Do you know how much of the processing power of a typical desktop machine we can utilize using only the core version of C++/Standard Library? 50%, 100%? 10%?[…] we can usually access only around 0,25% with single-threaded C++ code and maybe a few percent when you add threading from C++11/14.” (Sean Parent).
Przyznam szczerze, że nieco otworzyło mi to oczy:
GPU power | CPU vectorization | CPU threading | Single Thread |
---|---|---|---|
75% | 20% | 4% | 0,25% |
#include <iostream> #include <vector> #include <variant> #include <any> using namespace std; template <typename T1, typename T2> class T { T1 a; T2 b; public: T(T1 a, T2 b) : a(a), b(b) {} void show() { cout << a << b; } }; int main() { T<char, const char*> t1('C', "++"); T<int, const char*> t2(17, " nie taki straszny ;)\n"); T<string, int> t3("66.", 6); typedef variant<T<char, const char*>, T<int, const char*>, T<string, int>> var_t; vector<var_t> var_v {t1, t2, t3}; auto callShow = [](auto& obj) { obj.show(); }; for (auto& obj : var_v) std::visit(callShow, obj); cout << endl << "------" << endl; vector<any>anyv {1, 2.0, "trzy"}; for(auto &i: anyv) { if (i.type() == typeid(int)) cout << any_cast<int>(i) << endl; if (i.type() == typeid(double)) cout << any_cast<double>(i) << endl; if (i.type() == typeid(const char *)) cout << any_cast<const char *>(i) << endl; if (i.type() == typeid(string)) cout << any_cast<string>(i) << endl; } }
PS E:\cpp_fun> .\templ1.exe
C++17 nie taki straszny 😉
66.6
——
1
2
trzy
#include <iostream> #include <range/v3/all.hpp> #include <string> #include <vector> using namespace std; using namespace ranges; int main() { auto print = [](auto &i) {cout << i << " "; }; auto even = [](int i){ return 0 == i % 2; }; auto square = [](int i) { return i * i; }; auto end = ranges::end; vector<int> ints = views::ints(1, 50) | views::filter(even) | views::transform(square) | views::slice(end-5, end) | ranges::to<vector>(); ranges::for_each(ints, print); auto chars = views::iota('a', 'z'+1) | views::reverse | ranges::to<vector>(); ranges::for_each(chars, print); auto t = views::ints(0, 50) | views::filter([](int i) { return i<20 ? true : false; }) | ranges::to<vector>(); ranges::for_each(t, print); cout << endl; }
PS E:\cpp_fun> .\ranges2.exe
1600 1764 1936 2116 2304 z y x w v u t s r q p o n m l k j i h g f e d c b a 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
BTW: dzięki Bartkowi odkryłem, że nie boję się już lambd, a nawet je trochę lubię 😉