├── imgs ├── stl.png └── cpp_logo.png ├── docs ├── libs.org ├── courses.org ├── unit.tests.org ├── books.org ├── cpp17.inline.org ├── resources.org ├── cpp17.nested.org ├── trasnlation.unit.org ├── std_transform.org ├── functional.org ├── std_functional.org ├── dev.stack.org ├── multithreading.org ├── std_invoke.org ├── cpp17.initalizarif.org ├── cpp17.filesystem.org ├── std_accumulate.org ├── concepts.org ├── metaprogramming.org ├── cpp17.structure.binding.org ├── cpp17.template.deduction.org ├── cpp.functional.higherorderfunctions.org ├── exceptions.org ├── cpp17.anonym.org ├── name.mangling.org ├── basics.org ├── cpp17.string.view.org ├── lambda.recursive.org ├── cpp17.palgorithms.org ├── lambda.this.org ├── linking.org ├── lambda.callback.org ├── void.ptr.org ├── cpp17.initialization.list.org ├── deepshallowcopy.org ├── modern.cpp.org ├── multithreading.future.promises.org └── containers.and.iterators.org ├── LICENSE └── README.org /imgs/stl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NelsonBilber/cpp-overview/HEAD/imgs/stl.png -------------------------------------------------------------------------------- /imgs/cpp_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NelsonBilber/cpp-overview/HEAD/imgs/cpp_logo.png -------------------------------------------------------------------------------- /docs/libs.org: -------------------------------------------------------------------------------- 1 | #+TITLE: C++ Libraries 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | - [[https://www.qt.io/][Qt - C++ Gui Framework]] 6 | - [[https://www.boost.org/][Boost - Generic C++ library]] 7 | -------------------------------------------------------------------------------- /docs/courses.org: -------------------------------------------------------------------------------- 1 | #+TITLE: C++ Courses 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | 6 | ** Learn Advanced C++ Programming Course 7 | [[https://github.com/NelsonBilber/cpp.udemy.advancedcpp][Source Code]] 8 | -------------------------------------------------------------------------------- /docs/unit.tests.org: -------------------------------------------------------------------------------- 1 | #+TITLE: C++ Unit Tests 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | Check this small project using Google-Test 6 | 7 | [[https://github.com/NelsonBilber/cpp.unittests][C++ Unit Tests]] 8 | -------------------------------------------------------------------------------- /docs/books.org: -------------------------------------------------------------------------------- 1 | #+TITLE: C++ Books 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | C++ has a lot of good books for several levels of experience. Check this link [[https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list][The Definitive C++ Book Guide and List]] 6 | 7 | Personally recommend: 8 | 9 | - The C++ Programming Language 10 | - Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14 11 | - Modern C++ Design: Generic Programming and Design Patterns Applied [[https://github.com/NelsonBilber/cpp.loki][Loki]] 12 | -------------------------------------------------------------------------------- /docs/cpp17.inline.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Inline variables 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | 6 | *source code from:* 7 | https://stackoverflow.com/questions/38043442/how-do-inline-variables-work 8 | 9 | #+BEGIN_EXAMPLE C++ 10 | 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | struct Kath 17 | { 18 | static std::string const hi; 19 | }; 20 | 21 | inline std::string const Kath::hi = "Zzzzz..."; // Simpler! 22 | 23 | int main() 24 | { 25 | cout << Kath::hi << endl; 26 | return 0; 27 | } 28 | 29 | 30 | #+END_EXAMPLE 31 | -------------------------------------------------------------------------------- /docs/resources.org: -------------------------------------------------------------------------------- 1 | #+TITLE: C++ Resources 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | ** Links 6 | 7 | *** Blogs 8 | 9 | [[https://isocpp.org/blog/rss][ISO C++ Blog]] 10 | 11 | [[https://blogs.msdn.microsoft.com/vcblog/][Visual C++ team Blog]] 12 | 13 | [[https://arne-mertz.de/][Simplify C++]] 14 | 15 | [[https://blog.feabhas.com/][Sticky Bits]] 16 | 17 | [[https://www.fluentcpp.com/][Fluent C++]] 18 | 19 | *** Podcast 20 | 21 | [[http://cppcast.com/][Cpp Cast]] 22 | 23 | *** Cpp Code Guidelines 24 | [[https://github.com/isocpp/CppCoreGuidelines][Link]] 25 | -------------------------------------------------------------------------------- /docs/cpp17.nested.org: -------------------------------------------------------------------------------- 1 | #+TITLE: nested namespaces 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | *source from:* 6 | http://www.nuonsoft.com/blog/2017/08/01/c17-nested-namespaces/ 7 | 8 | 9 | #+BEGIN_EXAMPLE C++ 10 | 11 | // Before C++17 12 | 13 | namespace Core { 14 | namespace Graphics { 15 | namespace Rendering { 16 | class PostProcessor 17 | { 18 | }; 19 | } 20 | } 21 | } 22 | 23 | // After C++17 24 | 25 | namespace Core::Graphics::Rendering { 26 | class PostProcessor 27 | { 28 | }; 29 | } 30 | 31 | 32 | #+END_EXAMPLE 33 | 34 | -------------------------------------------------------------------------------- /docs/trasnlation.unit.org: -------------------------------------------------------------------------------- 1 | #+title: Translation Unit 2 | #+author: Nelson Rodrigues 3 | 4 | 5 | According to standard C++ (wayback machine link) : A translation unit is the basic unit of compilation in C++. It consists of the contents of a single source file, plus the contents of any header files directly or indirectly included by it, minus those lines that were ignored using conditional preprocessing statements. 6 | 7 | A single translation unit can be compiled into an object file, library, or executable program. 8 | 9 | The notion of a translation unit is most often mentioned in the contexts of the One Definition Rule, and templates. 10 | 11 | *Text from:* 12 | https://stackoverflow.com/questions/1106149/what-is-a-translation-unit-in-c 13 | -------------------------------------------------------------------------------- /docs/std_transform.org: -------------------------------------------------------------------------------- 1 | #+title: std::transform 2 | #+author: Nelson Rodrigues 3 | 4 | 5 | std::transform applies the given function to a range and stores the result in another range, beginning at d_first. 6 | 7 | *source code from:* https://en.cppreference.com/w/cpp/algorithm/transform 8 | 9 | 10 | #+BEGIN_EXAMPLE C++ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | int main() 19 | { 20 | std::string s("hello"); 21 | std::transform(s.begin(), s.end(), s.begin(), 22 | [](unsigned char c) -> unsigned char { return std::toupper(c); }); 23 | 24 | std::cout << s << std::endl; 25 | 26 | return 0; 27 | } 28 | 29 | #+END_EXAMPLE 30 | -------------------------------------------------------------------------------- /docs/functional.org: -------------------------------------------------------------------------------- 1 | #+TITLE: C++ Functional Programming 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | This is a very wide topic, It's a programming paradigm. With modern C++ has gain attention again. 5 | Next link presents "just a simple" example how can be used in C++. 6 | 7 | [[file:cpp.functional.higherorderfunctions.org][higher order function]] 8 | 9 | [[std_invoke.org][std::invoke]] 10 | 11 | [[std_functional.org][std::functional]] 12 | 13 | 14 | ** Other examples 15 | 16 | 17 | object A calls a function on object B 18 | 19 | A->B 20 | 21 | object A calls a function on object B and then B calls an function on object A 22 | 23 | A->B->A 24 | 25 | [[https://github.com/NelsonBilber/cpp.functional][Call Methods on other Objects]] 26 | 27 | Some examples how to use std::function<...> 28 | 29 | [[https://github.com/NelsonBilber/cpp.functional.programming][Source Code]] 30 | -------------------------------------------------------------------------------- /docs/std_functional.org: -------------------------------------------------------------------------------- 1 | #+Author: Nelson Bilber Rodrigues 2 | #+title: C++ 17 std::functional 3 | 4 | std::function is a templated object that is used to store and call any 5 | callable type, such as functions, objects, lambdas and the result of std::bind 6 | 7 | *source code from:* https://shaharmike.com/cpp/lambdas-and-functions/#std-function 8 | 9 | 10 | #+BEGIN_SRC C++ 11 | 12 | 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | 18 | 19 | void global_f() 20 | { 21 | cout << "global_f()" << endl; 22 | } 23 | 24 | struct Functor 25 | { 26 | void operator()() {cout << "Functor" << endl;} 27 | }; 28 | 29 | int main() 30 | { 31 | std::function f; 32 | cout << "sizeof(f): " << sizeof(f) << endl; 33 | 34 | f = global_f; 35 | f(); 36 | 37 | f = [](){cout << "lambda" << endl;}; 38 | f(); 39 | 40 | Functor functor; 41 | f = functor; 42 | f(); 43 | 44 | f = std::bind(global_f); 45 | f(); 46 | 47 | return 0; 48 | } 49 | 50 | #+END_SRC 51 | -------------------------------------------------------------------------------- /docs/dev.stack.org: -------------------------------------------------------------------------------- 1 | #+TITLE: C++ Stack Developement 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | It's important to establish a pipeline for development, C++ has plenty of tools to deal with this process. 6 | These are my weapons of choice: 7 | 8 | - Project organization: [[https://cmake.org/][Cmake]] 9 | - IDE: Emacs, Qt Creator 10 | - Unit Test (TDD, BDD): [[https://github.com/catchorg/Catch2][Catch2]] or [[https://github.com/google/googletest][Google Test]] 11 | - Fuzz Testing: [[https://llvm.org/docs/LibFuzzer.html][libFuzzer]] 12 | - Continuous Integration: [[https://docs.travis-ci.com/user/languages/cpp/][Travis CI]] 13 | - Static Analysis: [[http://cppcheck.sourceforge.net/][Cpp Check]] 14 | 15 | *** Use cases 16 | 17 | Follow /Work In Progress (WIP)/ [[https://github.com/NelsonBilber/algorithms][Algorithms]] I'm trying to apply these concepts. 18 | 19 | On other project [[https://github.com/NelsonBilber/cpp.unittests][C++ Unit Tests]] I have used Google-Tests for TDD and Travis for Continuous Integration 20 | 21 | -------------------------------------------------------------------------------- /docs/multithreading.org: -------------------------------------------------------------------------------- 1 | #+Title: C++ Multi-threading 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | Modern C++ adds new functions/options to deal with threads independent of Operating System. Lots of ideas we could talk about this topic, it's very important to know some techniques using threads. A simple network program with a GUI that is constantly listen for data, couldn't work properly without threads 6 | 7 | Concepts/ideas: 8 | 9 | - Thread management: Threads, locks, dead locks, ... 10 | - Communication between threads: Conditions variables, features, ... 11 | - Atomic Operations, Lock free data structures, ... 12 | - Models/Architectures: One writer and multiple readers, .... 13 | 14 | 15 | ** Qt - Worker Thread 16 | 17 | The follow example uses Qt polemic thread management to describe a [[https://github.com/NelsonBilber/Qt/tree/master/WorkerQueue][Worker Queue]] 18 | 19 | 20 | ** std::future and std::promise 21 | 22 | How to use future and promises with modern C++ 23 | 24 | [[file:multithreading.future.promises.org][std::future and std::promise]] 25 | 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Nelson Bilber Rodrigues 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/std_invoke.org: -------------------------------------------------------------------------------- 1 | #+Author: Nelson Bilber Rodrigues 2 | #+title: C++ 17 std::invoke 3 | 4 | 5 | *source code from:* https://en.cppreference.com/w/cpp/utility/functional/invoke 6 | 7 | 8 | #+BEGIN_SRC C++ 9 | 10 | 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | struct Foo 17 | { 18 | Foo(int num) : num_(num) {} 19 | void print_add(int i) const { std::cout << num_+i << '\n'; } 20 | int num_; 21 | }; 22 | 23 | void print_num(int i) 24 | { 25 | std::cout << i << '\n'; 26 | } 27 | 28 | struct PrintNum 29 | { 30 | void operator()(int i) const 31 | { 32 | std::cout << i << '\n'; 33 | } 34 | }; 35 | 36 | int main() 37 | { 38 | //invoke free function 39 | std::invoke(print_num, -9); 40 | 41 | //invoke a lambda 42 | std::invoke([]() {print_num(42); }); 43 | 44 | //Invoke a member function 45 | const Foo foo(25); 46 | std::invoke(&Foo::print_add, foo, 1); 47 | 48 | //invoke (access) a data member 49 | cout << "num_: " << std::invoke(&Foo::num_, foo) << endl; 50 | 51 | //invoke a function object 52 | std::invoke(PrintNum(), 18); 53 | 54 | return 0; 55 | } 56 | 57 | #+END_SRC 58 | 59 | -------------------------------------------------------------------------------- /docs/cpp17.initalizarif.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Initalizer if-statement 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | 6 | It's a good pratice the declarion and the use of varibale shoulbe be the closes as possible 7 | 8 | After C++17 we can use initalizer if-statement 9 | 10 | 11 | #+BEGIN_EXAMPLE C++ 12 | 13 | 14 | 15 | \\... 16 | 17 | if (auto r = getGlobalObjectByName(word); !r) r->doSomething; 18 | The semantics are: 19 | 20 | if (init-statement; condition) statement 21 | The only difference from the "traditional" if-statement is the init-statement, which initializes a variable in the block scope, similar to for-loops. 22 | 23 | \\... 24 | 25 | #+END_EXAMPLE 26 | 27 | *source from:* 28 | https://stackoverflow.com/questions/45999057/can-i-write-this-if-statement-with-a-variable-declaration-on-one-line 29 | 30 | 31 | #+BEGIN_EXAMPLE C++ 32 | #include 33 | 34 | using namespace std; 35 | 36 | bool IsVisible () { return true; } 37 | 38 | int main() 39 | { 40 | if( auto b = IsVisible(); true ) 41 | { 42 | cout << "is visible ... " << b << endl; 43 | } 44 | else 45 | { 46 | cout << "is not visible ... " << b << endl; 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | 53 | #+END_EXAMPLE 54 | -------------------------------------------------------------------------------- /docs/cpp17.filesystem.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Filesystem 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | compiler flags: -lstdc++fs 6 | 7 | *source code from:* 8 | http://www.modernescpp.com/index.php/c-17-more-details-about-the-library 9 | 10 | 11 | #+BEGIN_EXAMPLE 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | namespace fs = std::filesystem; 20 | 21 | 22 | int main() 23 | { 24 | std::cout << "Current path: " << fs::current_path() << std::endl; 25 | std::string dir= "sandbox/a/b"; 26 | fs::create_directories(dir); 27 | std::ofstream("sandbox/file1.txt"); 28 | fs::path symPath= fs::current_path() /= "sandbox"; 29 | symPath /= "syma"; 30 | fs::create_symlink("a", "symPath"); 31 | 32 | std::cout << "fs::is_directory(dir): " << fs::is_directory(dir) << std::endl; 33 | std::cout << "fs::exists(symPath): " << fs::exists(symPath) << std::endl; 34 | std::cout << "fs::symlink(symPath): " << fs::is_symlink(symPath) << std::endl; 35 | 36 | for(auto& p: fs::recursive_directory_iterator("sandbox")) 37 | { 38 | std::cout << p.path() << std::endl; 39 | } 40 | 41 | 42 | return 0; 43 | } 44 | 45 | #+END_EXAMPLE 46 | 47 | -------------------------------------------------------------------------------- /docs/std_accumulate.org: -------------------------------------------------------------------------------- 1 | #+Title: std::accumulate 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | Computes the sum of the given value init and the elements in the range [first, last] 6 | 7 | *source code from:* https://en.cppreference.com/w/cpp/algorithm/accumulate 8 | 9 | #+BEGIN_EXAMPLE C++ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | int main() 18 | { 19 | std::vector v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 20 | 21 | int sum = std::accumulate(v.begin(), v.end(), 0); 22 | 23 | int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies()); 24 | 25 | std::string s = std::accumulate(std::next(v.begin()), v.end(), 26 | std::to_string(v[0]), // start with first element 27 | [](std::string a, int b) { 28 | return a + '-' + std::to_string(b); 29 | }); 30 | 31 | std::cout << "sum: " << sum << '\n' 32 | << "product: " << product << '\n' 33 | << "dash-separated string: " << s << '\n'; 34 | } 35 | 36 | 37 | #+END_EXAMPLE 38 | -------------------------------------------------------------------------------- /docs/concepts.org: -------------------------------------------------------------------------------- 1 | * Concepts ( since C++20 ) 2 | 3 | Concepts were idealized to simply generic programming. To design some constraints to a generic type, code star to became difficult to read and hard to maintain. 4 | 5 | "So *concepts* are boolean predicates that are valid constant-expressions. A concept is a set of requirements on a set of template arguments" 6 | 7 | from book : " C++ Templates: The Complete Guide 2.0" 8 | 9 | #+begin_src C++ 10 | 11 | #include 12 | 13 | template 14 | concept bool Equal(){ 15 | return requires ( T a, T b) 16 | { 17 | {a == b} -> bool; 18 | {a != b} -> bool; 19 | }; 20 | } 21 | 22 | // Use of concepts !! 23 | bool areEqual( Equal a, Equal b) 24 | { 25 | return a == b; 26 | } 27 | 28 | int main() 29 | { 30 | std::cout << std::boolalpha << std::endl; 31 | std::cout << "areEqual(1, 5): " << areEqual(1, 5) << std::endl; 32 | std::cout << "areEqual(2, 2): " << areEqual(2, 2) << std::endl; 33 | std::cout << std::endl; 34 | 35 | return 0; 36 | } 37 | 38 | #+end_src 39 | 40 | Source code from : [[http://www.modernescpp.com/index.php/component/content/article/42-blog/functional/288-defintion-of-concepts?Itemid=239#h1-two-forms][ModernsCpp - two forms]] 41 | 42 | 43 | **** Reference 44 | 45 | [[http://www.stroustrup.com/good_concepts.pdf][Concepts: The Future of Generic Programming]] 46 | 47 | -------------------------------------------------------------------------------- /docs/metaprogramming.org: -------------------------------------------------------------------------------- 1 | #+TITLE: C++ Template/Metaprogramming 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | 6 | A very powerful programming technique. The follow examples explain how to use on functions and classes 7 | 8 | ** Functions 9 | - Arguments Deduction [[https://github.com/NelsonBilber/cpp.templates.functions.1.arguments.deduction][Source Code]] 10 | - Explicit Specialization [[https://github.com/NelsonBilber/cpp.templates.functions.2.explicit.specialization][Source Code]] 11 | - Non-Type Arguments [[https://github.com/NelsonBilber/cpp.templates.functions.3.non-type.arguments][Source Code]] 12 | - Variadic Templates [[https://github.com/NelsonBilber/cpp.templates.functions.4.variadic.templates][Source Code]] 13 | ** Classes 14 | - Basics [[https://github.com/NelsonBilber/cpp.templates.class1.basic][Source Code]] 15 | - Explicit Specialization [[https://github.com/NelsonBilber/cpp.templates.class1.basic][Source Code]] 16 | - Partial Specialization [[https://github.com/NelsonBilber/cpp.templates.class3.partial.specialization][Source Code]] 17 | - Alias [[https://github.com/NelsonBilber/cpp.templates.class4.typealias][Source Code]] 18 | 19 | ** Template Patterns 20 | 21 | - Tag Dispatching [[https://github.com/NelsonBilber/cpp.tag-dispatching][Source Code]] 22 | - C++ Curiously recurring template pattern [[https://github.com/NelsonBilber/cpp.crtp.template.pattern][Source Code]] 23 | 24 | ** since C++20 25 | 26 | - Concepts [[https://github.com/NelsonBilber/cpp-overview/blob/master/docs/concepts.org][More information ...]] 27 | 28 | -------------------------------------------------------------------------------- /docs/cpp17.structure.binding.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Structure unbinding 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | *from source code:* 6 | https://skebanga.github.io/structured-bindings/ 7 | 8 | #+BEGIN_EXAMPLE C++ 9 | 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | struct MyTuple { 18 | int a; 19 | std::string b; 20 | double c; 21 | }; 22 | 23 | std::map get_map() 24 | { 25 | return 26 | { 27 | { "hello", 1 }, 28 | { "world", 2 }, 29 | { "it's", 3 }, 30 | { "me", 4 }, 31 | }; 32 | } 33 | 34 | int main() 35 | { 36 | 37 | auto tuple = std::make_tuple(1,"3",5.23); 38 | int a; 39 | std::string b; 40 | double c; 41 | 42 | std::tie ( a, b, c ) = tuple; 43 | std::cout << a << " - " << b << " - " << c << std::endl; 44 | 45 | // Same code with C++17 Syntax 46 | 47 | auto [d,e,f] = tuple ; 48 | std::cout << d << " - " << e << " - " << f << std::endl; 49 | 50 | //obtain references 51 | auto& [g,h,j] = tuple ; 52 | g++; 53 | 54 | std::cout << g << " - " << h << " - " << j << std::endl; 55 | 56 | // with structs 57 | MyTuple tp {10, "my tuple", 102.112}; 58 | auto [k,l,m] = tp; 59 | 60 | std::cout << k << " - " << l << " - " << m << std::endl; 61 | 62 | MyTuple tp2 {11, "my tuple 2", 5.112}; 63 | std::vector v {tp, tp2}; 64 | 65 | for (const auto& [a, b, c] : v ) 66 | { 67 | std::cout << a << " - " << b << std::endl; 68 | } 69 | 70 | for (auto&& [ k, v ] : get_map()) 71 | { 72 | std::cout << "k=" << k << " v=" << v << '\n'; 73 | } 74 | 75 | return 0; 76 | } 77 | 78 | 79 | #+END_EXAMPLE 80 | -------------------------------------------------------------------------------- /docs/cpp17.template.deduction.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Template deduction 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | 6 | #+BEGIN_EXAMPLE C++ 7 | 8 | /* 9 | 10 | " ... What are template deduction guides in C++17? 11 | Template deduction guides are patterns associated with a template class that tell the compiler how to translate a set of parameter (and their types) into template arguments. 12 | 13 | The simplest example is that of std::vector and its constructor that takes an iterator pair. 14 | 15 | template 16 | void func(Iterator first, Iterator last) 17 | { 18 | vector v(first, last); 19 | } 20 | The compiler needs to figure out what vector’s T type will be. We know what the answer is; T should be typename std::iterator_traits::value_type. But how do we tell the compiler without having to type vector::value_type>? ..." 21 | 22 | https://isocpp.org/blog/2017/09/quick-q-what-are-template-deduction-guides-in-cpp17 23 | 24 | source code from; 25 | 26 | Template argument deduction for class templates 27 | Automatic template argument deduction much like how it's done for functions, but now including class constructors. 28 | 29 | template 30 | struct MyContainer { 31 | T val; 32 | MyContainer() : val() {} 33 | MyContainer(T val) : val(val) {} 34 | // ... 35 | }; 36 | MyContainer c1{ 1 }; // OK MyContainer 37 | MyContainer c2; // OK MyContainer 38 | 39 | 40 | */ 41 | 42 | 43 | #+END_EXAMPLE 44 | 45 | 46 | 47 | 48 | ** References: 49 | 50 | https://github.com/AnthonyCalandra/modern-cpp-features/blob/master/README.md#template-argument-deduction-for-class-templates 51 | 52 | https://blog.tartanllama.xyz/deduction-for-class-templates/ 53 | 54 | http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0091r3.html 55 | -------------------------------------------------------------------------------- /docs/cpp.functional.higherorderfunctions.org: -------------------------------------------------------------------------------- 1 | #+Author: Nelson Bilber Rodrigues 2 | #+title: Higher Order Functions 3 | 4 | 5 | " ... higher-order functions can take functions as argument or return them as result... " 6 | 7 | " ... Each programming language supporting programming in the functional 8 | style supports at least the three functions map, filter, and fold. 9 | map applies a function to each element of its list. 10 | filter removes all elements of a list not satisfying a condition. 11 | fold is the most powerful of the three ones. 12 | fold successively applies a binary operation to 13 | pairs of the list and therefore reduces the list to a value ... " 14 | 15 | map ------> std::transform 16 | filter ---> std::remove_if 17 | fold -----> std::accumulate 18 | 19 | *Source code and text Quoted from:* 20 | http://www.modernescpp.com/index.php/higher-order-functions 21 | 22 | 23 | 24 | #+BEGIN_SRC C++ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | using namespace std; 34 | 35 | int main() 36 | { 37 | std::vector str {"programming", "in", "a", "functional", "style"}; 38 | 39 | //map 40 | std::vector vec2; 41 | std::transform(str.begin(), str.end(), std::back_inserter(vec2), 42 | [](std::string s){ return s.length ();} ); 43 | for( auto&& v: vec2) { 44 | cout << v << " "; 45 | } 46 | cout << endl; 47 | 48 | //reduce 49 | std::vector str2 {"Programming", "in", "a", "functional", "style"}; 50 | auto it = std::remove_if (str2.begin(), str2.end(), 51 | [](std::string s){ return !(std::isupper(s[0]));}); 52 | cout << *it << endl; 53 | 54 | //fold 55 | std::vector str3 {"Programming", "in", "a", "functional", "style"}; 56 | std::accumulate(str3.begin(), str3.end(), string(""), 57 | [](std::string a,std::string b){ return a+":"+b; }); 58 | 59 | for( auto&& v: str3) { 60 | cout << v << " "; 61 | } 62 | cout << endl; 63 | return 0; 64 | } 65 | 66 | 67 | #+END_SRC 68 | 69 | -------------------------------------------------------------------------------- /docs/exceptions.org: -------------------------------------------------------------------------------- 1 | #+title: Exceptions 2 | #+author: Nelson Rodrigues 3 | 4 | 5 | C++ 17 exception and no-exception 6 | 7 | *Text and Source code:* 8 | https://msdn.microsoft.com/en-us/library/4tebey8h.aspx 9 | 10 | 11 | "... When the catch statement is reached, all of the automatic variables that are in scope 12 | between the throw and catch statements are destroyed in a process that is known as stack unwinding ..." 13 | 14 | *Text and Source code:* 15 | https://docs.microsoft.com/en-us/cpp/cpp/exceptions-and-stack-unwinding-in-cpp?view=vs-2017 16 | 17 | 18 | "... Prior to C++17 there were two kinds of exception specification. The noexcept specification 19 | was new in C++11. It specifies whether the set of potential exceptions that can escape the function 20 | is empty. The dynamic exception specification, or throw(optional_type_list) specification, was deprecated 21 | in C++11 and removed in C++17, except for throw(), which is an alias for noexcept(true). 22 | This exception specification was designed to provide summary information about what exceptions can be thrown 23 | out of a function, but in practice it was found to be problematic ..." 24 | 25 | *Text and Source code:* 26 | https://docs.microsoft.com/en-us/cpp/cpp/exception-specifications-throw-cpp?view=vs-2017 27 | 28 | 29 | *noexcept* 30 | -It turns an exception throw into a call to std::terminate(). 31 | -One can make a compile-time query if the function has been declared as noexcept. 32 | 33 | *Text and Source code:* 34 | https://akrzemi1.wordpress.com/2014/04/24/noexcept-what-for/ 35 | 36 | 37 | #+BEGIN_EXAMPLE C++ 38 | 39 | #include 40 | #include 41 | 42 | using namespace std; 43 | 44 | void test(int i) noexcept 45 | { 46 | if(i == 0) 47 | throw 2.0; 48 | else 49 | cout << "i = " << i << endl; 50 | } 51 | 52 | int main() 53 | { 54 | int * x = nullptr; 55 | try 56 | { 57 | test(10); 58 | test(0); 59 | 60 | x = new int(); 61 | throw 20; 62 | } 63 | catch ( double e ) 64 | { 65 | delete x; 66 | cout << "An exception (double) = " << e << endl; 67 | } 68 | catch ( int e ) 69 | { 70 | delete x; 71 | cout << "An exception (int) = " << e << endl; 72 | } 73 | 74 | cout << "end"; 75 | return 0; 76 | } 77 | 78 | #+END_EXAMPLE 79 | 80 | -------------------------------------------------------------------------------- /docs/cpp17.anonym.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Anonymous namespaces 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | **** Anonymous namespaces 5 | 6 | #+BEGIN_EXAMPLE C++ 7 | /* Unnamed/anonymous namespaces vs. static functions 8 | 9 | https://stackoverflow.com/questions/154469/unnamed-anonymous-namespaces-vs-static-functions 10 | 11 | -------------------------------------------------------------------------------------------------------- 12 | 13 | Anonymous Namespaces 14 | 15 | In C++, there exists another way to declare one or more symbols to have internal linkage: anonymous namespaces. Such a namespace ensures that the symbols declared inside it are visible only within the current translation unit. It is, in essence, just a way to declare many symbols as static. In fact, for a while, the static keyword for the use of declaring a symbol to have internal linkage was deprecated in favor of anonymous namespaces. However, it was recently undeprecated, because it is useful to declare a single variable or function to have internal linkage. There are also a few minor differences which I won’t go into here. 16 | 17 | In any case, this: 18 | 19 | namespace { int variable = 0; } 20 | does (almost) the same thing as this: 21 | 22 | static int variable = 0; 23 | 24 | http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/ 25 | 26 | ------------------------------------------------------------------------------------------------------------------- 27 | C++17 might simplify nested namespace definition: 28 | 29 | namespace A::B::C { 30 | } 31 | is equivalent to 32 | 33 | namespace A { namespace B { namespace C { 34 | } } } 35 | 36 | https://stackoverflow.com/questions/11358425/is-there-a-better-way-to-express-nested-namespaces-in-c-within-the-header 37 | 38 | */ 39 | 40 | #include 41 | 42 | namespace A::B::C { 43 | class Test{ 44 | public: 45 | Test() = default; 46 | }; 47 | } 48 | 49 | 50 | int main() 51 | { 52 | A::B::C::Test t {}; 53 | return 0; 54 | } 55 | 56 | 57 | /* 58 | 59 | How to use a anonymous namespaces to avoid the use of const static int = 42; 60 | 61 | on *.hpp file 62 | 63 | namespace TempDefinitions 64 | { 65 | const int32 CONTROLLER_ID_NOT_FOUND = -1; 66 | } 67 | 68 | 69 | On *.cpp file set up a variable for 70 | 71 | namespace 72 | { 73 | const int32 DEFAULT_ID = TempDefinitions::ID_NOT_FOUND; 74 | } 75 | 76 | 77 | // ... 78 | 79 | int x = DEFAULT_ID: 80 | 81 | */ 82 | 83 | #+END_EXAMPLE 84 | -------------------------------------------------------------------------------- /docs/name.mangling.org: -------------------------------------------------------------------------------- 1 | #+title:Name Mangling vs Virtual Functions vs Function Overloading 2 | #+author: Nelson Rodrigues 3 | 4 | 5 | In compiler construction, name mangling (also called name decoration) is a technique used to solve various problems caused by the need to resolve unique names for programming entities in many modern programming languages. 6 | It provides a way of encoding additional information in the name of a function, structure, class or another datatype in order to pass more semantic information from the compilers to linkers. 7 | The need arises where the language allows different entities to be named with the same identifier as long as they occupy a different namespace (where a namespace is typically defined by a module, class, or explicit namespace directive) or have different signatures (such as function overloading). 8 | Any object code produced by compilers is usually linked with other pieces of object code (produced by the same or another compiler) by a type of program called a linker. The linker needs a great deal of information on each program entity. For example, to correctly link a function it needs its name, the number of arguments and their types, and so on. 9 | https://en.wikipedia.org/wiki/Name_mangling 10 | 11 | In object-oriented programming, in languages such as C++, and Object Pascal, a virtual function or virtual method is an inheritable and overridable function or method for which dynamic dispatch is facilitated. This concept is an important part of the (runtime) polymorphism portion of object-oriented programming (OOP). In short, a virtual function defines a target function to be executed, but the target might not be known at compile time. 12 | https://en.wikipedia.org/wiki/Virtual_function 13 | 14 | Rules in function overloading 15 | The same function name is used for more than one function definition 16 | The functions must differ either by the arity or types of their parameters 17 | It is a classification of static polymorphism in which a function call is resolved using some "best match" algorithm, where the particular function to call is resolved by finding the best match of the formal parameter types with the actual parameter types. The details of this algorithm vary from language to language. 18 | Function overloading is usually associated with statically-typed programming languages that enforce type checking in function calls. An overloaded function is really just a set of different functions that happen to have the same name. 19 | 20 | https://en.wikipedia.org/wiki/Function_overloading 21 | -------------------------------------------------------------------------------- /docs/basics.org: -------------------------------------------------------------------------------- 1 | #+Title: C++ Basics 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | Important concepts about C++ programming language 5 | 6 | 7 | | Topic | Description | 8 | |-----------------------------------------------+------------------------------------------------------------------------------------------| 9 | | RAII | More information ... [[https://github.com/NelsonBilber/cpp.RAII][Source Code]] | 10 | | Containers | More information ... [[https://github.com/NelsonBilber/cpp.containers][Source Code]] | 11 | | Cast | More information ... [[https://github.com/NelsonBilber/cpp.cast][Source Code]] | 12 | | Smart Pointers | More information ... [[https://github.com/NelsonBilber/cpp.smartpointers][Source Code]] | 13 | | std::transform | More information ... [[file:std_transform.org][std::transform]] | 14 | | std::accumulate | More information ... [[file:std_accumulate.org][std::accumulate]] | 15 | | STL utils | More information ... [[https://github.com/NelsonBilber/cpp.stl][Source Code]] | 16 | | Exception | More information ... [[file:exceptions.org][exceptions]] | 17 | | Object Oriented programming | More information ... [[https://github.com/NelsonBilber/cpp.oop][Source Code]] | 18 | | The Rule of Three/five/zero | More information ... [[https://github.com/NelsonBilber/cpp.movesemantics][Source Code]] | 19 | | Translation Units | More information ... [[file:trasnlation.unit.org][Translation Unit]] | 20 | | Internal linking vs External Linking | More information ... [[file:linking.org][Internal and External Linking]] | 21 | | Name mangling vs Virtual Function Overloading | More information ... [[file:name.mangling.org][Name Mangling]] | 22 | | void* | More information ... [[file:void.ptr.org][void*]] | 23 | | Deep Copy and Shallow copy | More information ... [[file:deepshallowcopy.org][Deep and shallow copy]] | 24 | -------------------------------------------------------------------------------- /docs/cpp17.string.view.org: -------------------------------------------------------------------------------- 1 | #+TITLE: string_view 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | A wrapper/view from a tradiciona std::string. 6 | 7 | *source code from*: https://skebanga.github.io/string-view/ 8 | 9 | 10 | "... C++17 makes it easy by introducing a new type called std::string_view. From now on, if you are writing a function that accepts a string, 11 | use an std::string_view as parameter type. No need to use an std::string_view reference. A string_view is very cheap to copy, so it’s 12 | perfectly fine to pass by value. Basically, a string_view just contains a pointer to a string, and its length. A string_view parameter 13 | accepts any kind of string, such as a C++ std::string, a C-style const char* string, and a string literal, all without any copying involved! ..." 14 | 15 | *source from:* 16 | http://www.nuonsoft.com/blog/2018/06/06/c17-stdstring_view/ 17 | 18 | 19 | #+BEGIN_EXAMPLE C++ 20 | 21 | #include 22 | #include 23 | 24 | using namespace std; 25 | 26 | void* operator new(std::size_t n) 27 | { 28 | std::cout << "[allocating " << n << " bytes]\n"; 29 | return malloc(n); 30 | } 31 | 32 | bool compare(const std::string& s1, const std::string& s2) 33 | { 34 | if (s1 == s2) 35 | { 36 | return true; 37 | } 38 | std::cout << '\"' << s1 << "\" does not match \"" << s2 << "\"\n"; 39 | return false; 40 | } 41 | 42 | bool compare_v2(std::string_view s1, std::string_view s2) 43 | { 44 | if (s1 == s2) 45 | { 46 | return true; 47 | } 48 | std::cout << '\"' << s1 << "\" does not match \"" << s2 << "\"\n"; 49 | return false; 50 | } 51 | 52 | 53 | void processString(string_view myString) 54 | { 55 | cout << myString; if (myString.size() >= 4) 56 | { 57 | cout << " (Substring: " << myString.substr(2, 2) << ")"; 58 | } 59 | cout << endl; 60 | } 61 | 62 | int main() 63 | { 64 | string str = "this is my input string"; 65 | 66 | compare(str, "this is the first test string"); 67 | compare(str, "this is the second test string"); 68 | compare(str, "this is the third test string"); 69 | 70 | cout << "-------------------------------------------" << endl; 71 | 72 | compare_v2(str, "this is the first test string"); 73 | compare_v2(str, "this is the second test string"); 74 | compare_v2(str, "this is the third test string"); 75 | 76 | cout << "-------------------------------------------" << endl; 77 | 78 | string myString1 = "Hello"; 79 | const char* myString2 = "C++"; 80 | processString(myString1); // C++ string 81 | processString(myString2); // C-style string 82 | processString("World!"); // String literal 83 | 84 | return 0; 85 | } 86 | 87 | 88 | #+END_EXAMPLE 89 | -------------------------------------------------------------------------------- /docs/lambda.recursive.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Lambda recursive 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | " ... You can store it in a variable and reference that variable (although you cannot declare the type of that variable 5 | as auto, you would have to use an std::function object instead) ... " 6 | 7 | *Source code from*: 8 | https://stackoverflow.com/questions/14531993/can-lambda-functions-be-recursive/14532044 9 | 10 | http://cpptruths.blogspot.com/2013/10/creating-recursive-lambdas-and.html 11 | 12 | http://www.riptutorial.com/cplusplus/example/8508/recursive-lambdas 13 | 14 | 15 | 16 | 17 | ** *this vs this in C++ 18 | 19 | 20 | this is a pointer, and *this is a dereferenced pointer. 21 | 22 | ** source code example 23 | 24 | If you had a function that returned this, it would be a pointer to the current object, while a function that returned *this would be a "clone" of the current object, allocated on the stack -- unless you have specified the return type of the method to return a reference. 25 | 26 | *source code: * 27 | https://stackoverflow.com/questions/2750316/this-vs-this-in-c#2750322 28 | 29 | 30 | #+BEGIN_EXAMPLE C++ 31 | 32 | */ 33 | 34 | #include 35 | #include 36 | 37 | using namespace std; 38 | 39 | std::function create() { 40 | int foo = 20; 41 | std::function f = [=](int n) mutable { 42 | std::function recurse = [&](int n) { 43 | foo = 10; 44 | return (n<=2)? 1 : recurse(n-1) + recurse(n-2); 45 | }; 46 | return recurse(n); 47 | }; 48 | return f; 49 | } 50 | 51 | template < class F > 52 | struct y_combinator { 53 | F f; 54 | // forward operator() 55 | template 56 | decltype(auto) operator()(Args&&... args) const { 57 | return f(*this, std::forward(args)...); 58 | } 59 | }; 60 | 61 | //helper functions for deduce thr type of th lamnda 62 | template < class F > 63 | y_combinator< std::decay_t > make_y_combinator (F&& f){ 64 | return {std::forward(f)}; 65 | }; 66 | 67 | int main() 68 | { 69 | std::function factorial = [&] (int i) 70 | { 71 | return (i == 1) ? 1 : i * factorial(i - 1); 72 | }; 73 | 74 | //ERROR 75 | //When the function ends, so does the fib object and consequently, the reference inside the closure becomes invalid 76 | std::function fib = [&fib](int n) 77 | { 78 | return (n <= 2)? 1 : fib(n-1) + fib(n-2); 79 | }; 80 | 81 | cout << factorial(5) << endl; 82 | cout << fib(10) << endl; 83 | auto a = create(); 84 | cout << a(10) << endl; 85 | 86 | auto gcd = make_y_combinator( 87 | [](auto&& gcd, int a, int b){ 88 | return b == 0 ? a : gcd(b, a%b); 89 | } 90 | ); 91 | 92 | 93 | return 0; 94 | } 95 | 96 | #+END_EXAMPLE 97 | 98 | -------------------------------------------------------------------------------- /docs/cpp17.palgorithms.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Parallel Algorithms 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | 6 | 7 | 8 | ** Supported Algorithm 9 | ------------------- 10 | 11 | C++17 in details: Parallel Algorithms 12 | 13 | http://www.modernescpp.com/index.php/parallel-algorithm-of-the-standard-template-library 14 | 15 | ** Execution policies 16 | 17 | The execution policy parameter will tell the algorithm how it should be executed. We have the following options: 18 | 19 | sequenced_policy - is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and require that a parallel algorithm’s execution may not be parallelized. 20 | the corresponding global object is std::execution::seq 21 | parallel_policy - is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and indicate that a parallel algorithm’s execution may be parallelized. 22 | the corresponding global object is std::execution::par 23 | parallel_unsequenced_policy - is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and indicate that a parallel algorithm’s execution may be parallelized and vectorized. 24 | the corresponding global object is std::execution::par_unseq 25 | 26 | *text extracted from*: https://www.bfilipek.com/2017/08/cpp17-details-parallel.html 27 | 28 | *source code based from*: https://stackoverflow.com/questions/21516575/fill-a-vector-with-random-numbers-c 29 | 30 | 31 | #+BEGIN_SRC C++ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | using namespace std; 40 | 41 | void print(const vector& vec) 42 | { 43 | for( auto& i: vec) 44 | { 45 | cout << i << " "; 46 | } 47 | cout << endl; 48 | } 49 | 50 | int main() 51 | { 52 | random_device rnd_device; 53 | mt19937 mersenne_engine {rnd_device()}; 54 | uniform_int_distribution dist {1, 52}; 55 | 56 | auto gen = [&dist, &mersenne_engine](){ return dist(mersenne_engine);}; 57 | 58 | vector vec(100); 59 | std::generate(begin(vec), end(vec), gen); 60 | print(vec); 61 | 62 | cout << "standard sort" << endl; 63 | std::sort(vec.begin(), vec.end()); 64 | print(vec); 65 | 66 | std::shuffle(begin(vec), end(vec), mersenne_engine); 67 | 68 | cout << "Sequential sort" << endl; 69 | std::sort(std::execution::seq, vec.begin(), vec.end()); 70 | print(vec); 71 | 72 | std::shuffle(begin(vec), end(vec), mersenne_engine); 73 | cout << "Permiting parallel execution sort" << endl; 74 | std::sort(std::execution::par, vec.begin(), vec.end()); 75 | print(vec); 76 | 77 | std::shuffle(begin(vec), end(vec), mersenne_engine); 78 | cout << "Permiting parallel and vectorization execution sort" << endl; 79 | std::sort(std::execution::par_unseq, vec.begin(), vec.end()); 80 | print(vec); 81 | 82 | return 0; 83 | } 84 | 85 | #+END_SRC 86 | 87 | 88 | |-|-| 89 | -------------------------------------------------------------------------------- /docs/lambda.this.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Lambda capture (*this) 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | C++ lambda capture this by value 6 | https://stackoverflow.com/questions/33575563/c-lambda-capture-this-vs-capture-by-reference 7 | 8 | *source code from:* 9 | https://crascit.com/2015/03/01/lambdas-for-lunch/ 10 | 11 | 12 | 13 | #+begin_src C++ 14 | 15 | 16 | /* 17 | 18 | struct S { void f(int i); }; 19 | 20 | void S::f(int i) { 21 | [&, i]{}; // OK 22 | [&, &i]{}; // ERROR: i preceded by & when & is the default 23 | [=, this]{}; // ERROR: this when = is the default 24 | [=, *this]{ }; // OK: captures this by value. See below. 25 | [i, i]{}; // ERROR: i repeated 26 | } 27 | 28 | "... he this pointer may be captured by value by specifying *this in the capture clause. Capture by value means that the entire closure, which is the anonymous function object that encapulates the lambda expression, is copied to every call site where the lambda is invoked. Capture by value is useful when the lambda will execute in parallel or asynchronous operations, especially on certain hardware architectures such as NUMA...." 29 | 30 | https://docs.microsoft.com/en-us/cpp/cpp/lambda-expressions-in-cpp?view=vs-2017 31 | 32 | */ 33 | 34 | #+end_src 35 | 36 | #+begin_src C++ 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | using namespace std; 43 | 44 | class Foo 45 | { 46 | int x; 47 | public: 48 | Foo() : x(10) {} 49 | 50 | /* 51 | Capturing the this pointer is particularly convenient and 52 | lambdas often make use of this capability. Note that capturing 53 | this by reference doesn’t really make sense (you can’t change 54 | its value), so it should always appear in a capture statement 55 | as capturing by value. 56 | 57 | [this] - captures by value, same result as [=] 58 | 59 | */ 60 | void bar() 61 | { 62 | // Increment x every time we are called 63 | auto lam = [this](){ return ++x; }; 64 | std::cout <<"lam () => " < returnType {body} 71 | auto fun = [](double t){ return t*t;}; 72 | cout << "square(5) = " << fun(5) << endl; 73 | 74 | vector v {23, -5, -2 , 16, 20}; 75 | auto c = count_if(v.begin(), v.end(), 76 | [](int i){ return i == ((i/5)* 77 | cout << c << endl; 78 | 79 | int x = 5; 80 | auto copyLambda = [x](){ return x; }; 81 | auto refLambda = [&x](){ return x; }; 82 | 83 | std::cout << copyLambda() << std::endl; 84 | std::cout << refLambda() << std::endl; 85 | x = 7; 86 | std::cout << copyLambda() << std::endl; 87 | std::cout << refLambda() << std::endl; 88 | 89 | Foo foo; 90 | foo.bar(); // Outputs 11 91 | foo.bar(); // Outputs 12 92 | 93 | int mm = 5; 94 | auto inc = [&mm](){ return ++mm;}; 95 | cout << "inc() = "<< inc() << endl; 96 | } 97 | 98 | 99 | #+end_src 100 | -------------------------------------------------------------------------------- /docs/linking.org: -------------------------------------------------------------------------------- 1 | #+title: Internal linking vs External Linking 2 | #+author: Nelson Rodrigues 3 | 4 | 5 | A1: 6 | 7 | When you write an implementation file (.cpp, .cxx, etc) your compiler generates a translation unit. This is the object file from your implementation file plus all the headers you #included in it. 8 | *Internal linkage* refers to everything only in scope of a translation unit. 9 | *External linkage* refers to things that exist beyond a particular translation unit. In other words, accessible through the whole program, which is the combination of all translation units (or object files). 10 | 11 | A2: 12 | 13 | As dudewat said external linkage means the symbol (function or global variable) is accessible throughout your program and internal linkage means that it's only accessible in one translation unit. 14 | 15 | You can explicitly control the linkage of a symbol by using the extern and static keywords. If the linkage isn't specified then the default linkage is extern for non-const symbols and static (internal) for const symbols. 16 | 17 | #+BEGIN_SRC C++ 18 | 19 | // in namespace or global scope 20 | int i; // extern by default 21 | const int ci; // static by default 22 | extern const int eci; // explicitly extern 23 | static int si; // explicitly static 24 | 25 | // the same goes for functions (but there are no const functions) 26 | int foo(); // extern by default 27 | static int bar(); // explicitly static 28 | 29 | #+END_SRC 30 | 31 | Note that instead of using static for internal linkage it is better to use anonymous namespaces into which you can also put classes. The linkage for anonymous namespaces has changed between C++98 and C++11 but the main thing is that they are unreachable from other translation units. 32 | 33 | #+BEGIN_SRC C++ 34 | 35 | namespace { 36 | int i; // external linkage but unreachable from other translation units. 37 | class invisible_to_others { }; 38 | } 39 | 40 | #+END_SRC 41 | 42 | 43 | A3: 44 | 45 | A translation unit refers to an implementation (.c/.cpp) file and all header (.h/.hpp) files it includes. If an object or function inside such a translation unit has internal linkage, then that specific symbol is only visible to the linker within that translation unit. If an object or function has external linkage, the linker can also see it when processing other translation units. The static keyword, when used in the global namespace, forces a symbol to have internal linkage. The extern keyword results in a symbol having external linkage. 46 | 47 | The compiler defaults the linkage of symbols such that: 48 | 49 | Non-const global variables have external linkage by default 50 | Const global variables have internal linkage by default 51 | Functions have external linkage by default 52 | 53 | *Text extracted from:* 54 | 55 | http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/ 56 | 57 | https://stackoverflow.com/questions/1358400/what-is-external-linkage-and-internal-linkage 58 | 59 | http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/ 60 | 61 | https://stackoverflow.com/questions/998425/why-does-const-imply-internal-linkage-in-c-when-it-doesnt-in-c 62 | -------------------------------------------------------------------------------- /docs/lambda.callback.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Using lambda as callback 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | #+BEGIN_SRC C++ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | //mix old C code just for concept proof 11 | #include 12 | 13 | using namespace std; 14 | 15 | //class with callbacks 16 | class WorkingClass 17 | { 18 | public: 19 | typedef const std::function handler_t; 20 | 21 | void AddHandler(handler_t& h) 22 | { 23 | handlerList.push_back(&h); 24 | } 25 | 26 | void DoStuff() 27 | { 28 | for(auto& handler: handlerList) 29 | { 30 | (*handler)(42); 31 | (*handler)(23); 32 | } 33 | } 34 | 35 | private: 36 | std::vector handlerList; 37 | 38 | }; 39 | 40 | //using legacy coe 41 | void do_something( void(*callback)(void*), void* callback_arg) 42 | { 43 | callback(callback_arg); 44 | } 45 | 46 | //tradicional functor in c++ (overload operator() ) 47 | //used for: e.g.:function with state 48 | struct AddF 49 | { 50 | AddF(int x): x(x) {} 51 | int operator()(int y) const { return x + y; } 52 | private: 53 | int x; 54 | }; 55 | 56 | 57 | /* tradicional functors in Plain C */ 58 | void fun(int a) 59 | { 60 | printf("value %d", a); 61 | } 62 | 63 | int main() 64 | { 65 | /* Exercise 01 */ 66 | WorkingClass wc; 67 | wc.AddHandler([&](int num){ cout << "A: " << num << endl; } ); 68 | wc.AddHandler([&](int num){ cout << "B: " << num << endl; } ); 69 | wc.DoStuff(); 70 | 71 | /* Exercise 02 */ 72 | int num_callbacks = 0; 73 | auto callback =[&](){ 74 | std::cout << "callback called " << ++num_callbacks << " times \n"; 75 | }; 76 | 77 | auto thunk = [](void* arg){ 78 | (*static_cast(arg))(); 79 | }; 80 | 81 | do_something(thunk, &callback); 82 | 83 | /* Exercise 03 */ 84 | auto lambda = [](int a, float b) { 85 | std::cout << "a: " << a << std::endl; 86 | std::cout << "b: " << b << std::endl; 87 | }; 88 | //function being a raw pointer 89 | auto function = static_cast(lambda); 90 | function(1, 2.13); 91 | //function begin a std::function 92 | auto function2 = static_cast>(lambda); 93 | function2(1, 2.13); 94 | 95 | 96 | 97 | // C++ tradicional functors 98 | AddF ff(3); 99 | int fff = ff(7); 100 | std::cout << fff << std::endl; 101 | 102 | 103 | 104 | // C tradiciona function pointer 105 | // return type( *name of var )(args01,args02, ...) 106 | void(*fun_ptr)(int) = &fun; 107 | /* The above line is equivalent of following two 108 | void (*fun_ptr)(int); 109 | fun_ptr = &fun;*/ 110 | (*fun_ptr)(10); // de-referencing a function pointer and add variables 111 | 112 | return 0; 113 | } 114 | 115 | #+END_SRC 116 | 117 | 118 | ** References 119 | 120 | https://gist.github.com/4poc/3155832 121 | http://bannalia.blogspot.com/2016/07/passing-capturing-c-lambda-functions-as.html 122 | https://embeddedartistry.com/blog/2017/1/26/c11-improving-your-callback-game 123 | 124 | # this blog has a complex example "Type safe callbacks (full example, supports capturing lambdas)" 125 | http://meh.schizofreni.co/programming/magic/2013/01/23/function-pointer-from-lambda.html 126 | 127 | # functors in c++ 128 | https://stackoverflow.com/questions/356950/what-are-c-functors-and-their-uses 129 | 130 | # function pointers in C 131 | https://www.geeksforgeeks.org/function-pointer-in-c/ 132 | 133 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | #+TITLE: C++ Overview 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | #+CAPTION: C++ ISO Logo 6 | #+NAME: C++ ISO logo 7 | #+ATTR_HTML: width="100px" 8 | #+ATTR_ORG: :width 100 9 | #+ATTR_HTML: :style margin-left: auto; margin-right: auto; 10 | [[./imgs/cpp_logo.png]] 11 | 12 | 13 | This repository collects source code about multiple topics about C++ programming language. The propose is to explore basic concepts ( RAII, Rule of 3 and 5 ) and more complex ideas ( Lambdas, move semantics, variadic templates, ... ). 14 | 15 | Also presents useful resources for implement a workflow for a stack of development, references to improve and get the last news of C++. 16 | 17 | Checkout my [[https://nelsonbilber.github.io][homepage]] for an alternative index and explore other technical programming topics. 18 | 19 | 20 | | Topic | Description | 21 | |--------------------------+-----------------------------------------------------------------------------------------------------------------| 22 | | [[file:./docs/basics.org][Basics]] | RAII, Containers, Rule of Three, Five and Zero, Exceptions, Linking, void*, ... | 23 | | [[file:./docs/containers.and.iterators.org][Containers and Iterators]] | STL Containers and Iterators | 24 | | [[file:./docs/modern.cpp.org][Modern C++ (11/14/17)]] | Lambdas ( recursive, *this), Concepts, Move semantics, Monads, C++ 17 | 25 | | [[file:./docs/metaprogramming.org][Template/Metaprogramming]] | Argument Type Deduction, Explicit Specialization, Variadic Templates, Partial Specialization, Concepts ( C++20) | 26 | | [[file:./docs/functional.org][Functional Programming]] | Small example how to use std | 27 | | [[file:./docs/multithreading.org][Multithreading]] | "Working Queue Model" with Qt, std::future and std::promises | 28 | | [[file:./docs/unit.tests.org][Unit Tests]] | How to use Google-tests for unit testing (TDD) | 29 | | [[file:./docs/dev.stack.org][Stack Of Developement]] | Recommendations for libs and tricks during all development cycles | 30 | | [[file:./docs/libs.org][Libraries]] | Popular C++ libs | 31 | | [[file:./docs/courses.org][Courses]] | Web courses to polish C++ code skills | 32 | | [[file:./docs/books.org][Books]] | Recomended books that covers basic and advanced concepts and best practices | 33 | | [[file:./docs/resources.org][Resources]] | Links, blogs, podcast, ... | 34 | |--------------------------+-----------------------------------------------------------------------------------------------------------------| 35 | 36 | **** Quick Access 37 | 38 | [[https://github.com/NelsonBilber/cpp_clean_project][Clean C++ Project Template]] 39 | 40 | **** Logo Copyrights 41 | 42 | [[https://github.com/isocpp/logos][C++ Standard Foundation]] 43 | -------------------------------------------------------------------------------- /docs/void.ptr.org: -------------------------------------------------------------------------------- 1 | #+title: void* 2 | #+author: Nelson Rodrigues 3 | 4 | 5 | *void pointers* 6 | The void type of pointer is a special type of pointer. In C++, void represents the absence of type. Therefore, void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereferencing properties). 7 | 8 | This gives void pointers a great flexibility, by being able to point to any data type, from an integer value or a float to a string of characters. In exchange, they have a great limitation: the data pointed to by them cannot be directly dereferenced (which is logical, since we have no type to dereference to), and for that reason, any address in a void pointer needs to be transformed into some other pointer type that points to a concrete data type before being dereferenced. 9 | 10 | One of its possible uses may be to pass generic parameters to a function. For example: 11 | 12 | *Text from:* 13 | http://www.cplusplus.com/doc/tutorial/pointers/ 14 | 15 | 16 | A pointer to void is a "generic" pointer type. A void * can be converted to any other pointer type without an explicit cast. You cannot dereference a void * or do pointer arithmetic with it; you must convert it to a pointer to an complete data type first. 17 | 18 | It gets used in places where you need to be able to work with different pointer types in the same code. One commonly cited example is the library function qsort: 19 | 20 | #+begin_src C++ 21 | 22 | void qsort(void *base, size_t nmemb, size_t size, 23 | int (*compar)(const void *, const void *)); 24 | base is the address of an array, nmemb is the number of elements in the array, size is the size of each element, and compar is a pointer to a function that compares two elements of the array. It gets called like so: 25 | 26 | int iArr[10]; 27 | double dArr[30]; 28 | long lArr[50]; 29 | ... 30 | qsort(iArr, sizeof iArr/sizeof iArr[0], sizeof iArr[0], compareInt); 31 | qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareDouble); 32 | qsort(lArr, sizeof lArr/sizeof lArr[0], sizeof lArr[0], compareLong); 33 | The array expressions iArr, dArr, and lArr are implicitly converted from array types to pointer types in the function call, and each is implicitly converted from "pointer to int/double/long" to "pointer to void". 34 | 35 | //The comparison functions would look something like: 36 | 37 | int compareInt(const void *lhs, const void *rhs) 38 | { 39 | const int *x = lhs; // convert void * to int * by assignment 40 | const int *y = rhs; 41 | 42 | if (*x > *y) return 1; 43 | if (*x == *y) return 0; 44 | return -1; 45 | } 46 | 47 | #+end_src 48 | 49 | By accepting void *, qsort can work with arrays of any type. 50 | 51 | The disadvantage of using void * is that you throw type safety out the window and into oncoming traffic. There's nothing to protect you from using the wrong comparison routine: 52 | 53 | qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareInt); 54 | compareInt is expecting its arguments to be pointing to ints, but is actually working with doubles. There's no way to catch this problem at compile time; you'll just wind up with a mis-sorted array. 55 | 56 | *Text from:* 57 | https://stackoverflow.com/questions/11626786/what-does-void-mean-and-how-to-use-it 58 | 59 | 11 standard (n1570) §6.2.2.3 al1 p55 says : 60 | A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer. 61 | You can use this generic pointer to store a pointer to any object type, but you can't use usual arithmetic operations with it and you can't deference it. 62 | 63 | *Text from:* 64 | https://stackoverflow.com/questions/11626786/what-does-void-mean-and-how-to-use-it 65 | -------------------------------------------------------------------------------- /docs/cpp17.initialization.list.org: -------------------------------------------------------------------------------- 1 | #+title: C++ 17 New rules for initalization Lists 2 | #+author: Nelson Bilber Rodrigues 3 | 4 | 5 | ** C++ Initalization types 6 | 7 | *source code from*: https://en.cppreference.com/w/cpp/language/initialization 8 | 9 | #+begin_src C++ 10 | 11 | Value initialization, e.g. std::string s{}; 12 | Direct initialization, e.g. std::string s("hello"); 13 | Copy initialization, e.g. std::string s = "hello"; 14 | List initialization, e.g. std::string s{'a', 'b', 'c'}; 15 | Aggregate initialization, e.g. char a[3] = {'a', 'b'}; 16 | Reference initialization, e.g. char& c = a[0]; 17 | 18 | #+end_src 19 | 20 | *source code from*: http://www.nuonsoft.com/blog/2017/08/09/c17-direct-vs-copy-list-initialization/ 21 | 22 | 23 | ** C++ 17 New rules for initalization Lists 24 | 25 | Fixes some cases with auto type deduction. The full background can be found in Auto and braced-init-lists, by Ville Voutilainen. 26 | 27 | It fixes the problem of deducing std::initializer_list like: 28 | 29 | #+BEGIN_SRC C++ 30 | auto x = foo(); // copy-initialization 31 | auto x{foo}; // direct-initialization, initializes an initializer_list 32 | int x = foo(); // copy-initialization 33 | int x{foo}; // direct-initialization 34 | And for the direct initialization, new rules are: 35 | 36 | For a braced-init-list with only a single element, auto deduction will deduce from that entry; 37 | For a braced-init-list with more than one element, auto deduction will be ill-formed. 38 | Basically, auto x { 1 }; will be now deduced as int, but before it was an initializer list. 39 | 40 | #+END_SRC 41 | 42 | 43 | *source code from*: https://www.bfilipek.com/2017/01/cpp17features.html#new-auto-rules-for-direct-list-initialization 44 | 45 | 46 | ** C++ std::initializer_list 47 | 48 | https://en.cppreference.com/w/cpp/utility/initializer_list 49 | 50 | std::initializer_list 51 | An object of type std::initializer_list is a lightweight proxy object that provides access to an array of objects of type const T. 52 | 53 | *benefits of using initalization_list* 54 | https://stackoverflow.com/questions/40818262/benefits-of-stdinitializer-list-in-c11 55 | 56 | *Source code from* : https://www.learncpp.com/cpp-tutorial/10-7-stdinitializer_list/ 57 | 58 | #+BEGIN_SRC C++ 59 | 60 | #include // for assert() 61 | #include // for std::initializer_list 62 | #include 63 | 64 | class IntArray 65 | { 66 | private: 67 | int m_length; 68 | int *m_data; 69 | 70 | public: 71 | IntArray() : 72 | m_length(0), m_data(nullptr) 73 | { 74 | } 75 | 76 | IntArray(int length) : 77 | m_length(length) 78 | { 79 | m_data = new int[length]; 80 | } 81 | 82 | IntArray(const std::initializer_list &list): // allow IntArray to be initialized via list initialization 83 | IntArray(list.size()) // use delegating constructor to set up initial array 84 | { 85 | // Now initialize our array from the list 86 | int count = 0; 87 | for (auto &element : list) 88 | { 89 | m_data[count] = element; 90 | ++count; 91 | } 92 | } 93 | 94 | ~IntArray() 95 | { 96 | delete[] m_data; 97 | // we don't need to set m_data to null or m_length to 0 here, since the object will be destroyed immediately after this function anyway 98 | } 99 | 100 | int& operator[](int index) 101 | { 102 | assert(index >= 0 && index < m_length); 103 | return m_data[index]; 104 | } 105 | 106 | int getLength() { return m_length; } 107 | }; 108 | 109 | int main() 110 | { 111 | IntArray array { 5, 4, 3, 2, 1 }; // initializer list 112 | for (int count = 0; count < array.getLength(); ++count) 113 | { 114 | std::cout << array[count] << ' '; 115 | } 116 | 117 | return 0; 118 | } 119 | 120 | #+END_SRC 121 | -------------------------------------------------------------------------------- /docs/deepshallowcopy.org: -------------------------------------------------------------------------------- 1 | #+title: Deep copy vs shallow copy 2 | #+author: Nelson Rodrigues 3 | 4 | 5 | Note. differences is on copy constructor() 6 | 7 | With a shallow copy, if the thing you're copying has a pointer to some data, you don't make a copy of that data and both objects (the original and the copy) share that same data (so changing the data in one object also changes it in the other, because they're both using that exact same data). 8 | 9 | 10 | 11 | Difference between Shallow copy and Deep copy 12 | 13 | An object copy is a process where a data object has its attributes copied to another object of the same data type. In .Net Shallow copy and deep copy are used for copying data between objects. 14 | 15 | What is Shallow copy ? 16 | shallow-copy c# vb.net 17 | 18 | Shallow copying is creating a new object and then copying the non static fields of the current object to the new object. If the field is a value type, a bit by bit copy of the field is performed. If the field is a reference type, the reference is copied but the referred object is not, therefore the original object and its clone refer to the same object. A shallow copy of an object is a new object whose instance variables are identical to the old object. In .Net shallow copy is done by the object method MemberwiseClone(). 19 | 20 | The situations like , if you have an object with values and you want to create a copy of that object in another variable from same type, then you can use shallow copy, all property values which are of value types will be copied, but if you have a property which is of reference type then this instance will not be copied, instead you will have a reference to that instance only. 21 | 22 | What is Deep copy ? 23 | deep-copy c# vb.net 24 | 25 | Deep copy is creating a new object and then copying the non-static fields of the current object to the new object. If a field is a value type, a bit by bit copy of the field is performed. If a field is a reference type, a new copy of the referred object is performed. A deep copy of an object is a new object with entirely new instance variables, it does not share objects with the old. While performing Deep Copy the classes to be cloned must be flagged as [Serializable]. 26 | 27 | Deep copy is intended to copy all the elements of an object, which include directly referenced elements of value type and the indirectly referenced elements of a reference type that holds a reference to a memory location that contains data rather than containing the data itself. 28 | 29 | *Text and code from:* 30 | https://owlcation.com/stem/Copy-Constructor-shallow-copy-vs-deep-copy 31 | 32 | 33 | #+BEGIN_SRC C++ 34 | 35 | #include "stdafx.h" 36 | #include 37 | using namespace std; 38 | 39 | class ShalloC 40 | { 41 | //Sample 01: Private Data Member 42 | private: 43 | int * x; 44 | 45 | public: 46 | //Sample 02: Constructor with single parameter 47 | ShalloC(int m) 48 | { 49 | x = new int; 50 | *x = m; 51 | } 52 | 53 | //Sample 08: Introduce Copy Constructor and perform Deep Copy 54 | ShalloC(const ShalloC& obj) 55 | { 56 | x = new int; 57 | *x = obj.GetX(); 58 | } 59 | 60 | //Sample 03: Get and Set Functions 61 | int GetX() const 62 | { 63 | return *x; 64 | } 65 | void SetX(int m) 66 | { 67 | *x = m; 68 | } 69 | 70 | //Sample 04: Print Function 71 | void PrintX() 72 | { 73 | cout << "Int X=" << *x << endl; 74 | } 75 | 76 | //Sample 05: DeAllocate the heap 77 | ~ShalloC() 78 | { 79 | delete x; 80 | } 81 | }; 82 | 83 | int main() 84 | { 85 | //Sample 06: Create Object 1 and copy that to Object 2. 86 | // Print the data member for both Object 1 & 2. 87 | ShalloC ob1(10); 88 | ShalloC ob2 = ob1 ; 89 | ob1.PrintX(); 90 | ob2.PrintX(); 91 | 92 | //Sample 07: Change the Data member value of Object 1 93 | // And print both Object 1 and Object 2 94 | ob1.SetX(12); 95 | ob1.PrintX(); 96 | ob2.PrintX(); 97 | } 98 | 99 | #+END_SRC 100 | 101 | http://net-informations.com/faq/net/shallow-deep-copy.htm 102 | -------------------------------------------------------------------------------- /docs/modern.cpp.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Modern C++ (11\14\17) 2 | #+AUTHOR: Nelson Rodrigues 3 | 4 | 5 | *** C++17 6 | 7 | | Topic | Description | 8 | |--------------------------+-----------------------------------------------------------------------| 9 | | initalization list | more (...) [[file:cpp17.initialization.list.org][Initalization List]] | 10 | | inline variables | more (...) [[file:cpp17.inline.org][inline variables]] | 11 | | anonymous namespaces | more (...) [[file:cpp17.anonym.org][anonymous namespaces]] | 12 | | nested namespaces | more (...) [[file:cpp17.nested.org][nested namespaces]] | 13 | | template decuction | more (...) [[file:cpp17.template.deduction.org][template deduction]] | 14 | | initializer if-statement | more (...) [[file:cpp17.initalizarif.org][initializer if-statement]] | 15 | | structure unbinding | more (...) [[file:cpp17.structure.binding.org][structure binding]] | 16 | | string_view | more (...) [[file:cpp17.string.view.org][string_view]] | 17 | | filesystem | more (...) [[file:cpp17.filesystem.org][filesystem]] | 18 | | parallel algorithms | more (...) [[file:cpp17.palgorithms.org][Parallel Algorithms]] | 19 | 20 | 21 | 22 | *** Lambdas 23 | 24 | 25 | | Topic | Description | 26 | |-----------------------------+----------------------------------------------------------------------------| 27 | | lambda recursive | more (...) [[file:lambda.recursive.org][lambda recursive]] | 28 | | capture *this (c++17) | more (...) [[file:lambda.this.org][*this (C++17)]] | 29 | | lambdas as callback | more (...) [[file:lambda.callback.org][lambda as callback]] | 30 | | monads | more (...) [[https://github.com/NelsonBilber/cpp.monads][Source Code]] | 31 | | others | more (...) [[https://github.com/NelsonBilber/cpp.lambdas][Source Code]] | 32 | 33 | 34 | *** mutable 35 | 36 | Mutable keyword can be used for change a value using a const function 37 | 38 | *source:* https://stackoverflow.com/questions/105014/does-the-mutable-keyword-have-any-purpose-other-than-allowing-the-variable-to 39 | 40 | 41 | #+BEGIN_EXAMPLE C++ 42 | 43 | #include 44 | 45 | using namespace std; 46 | 47 | class Test 48 | { 49 | public: 50 | Test() = default; 51 | 52 | //silly method just for demonstration prospose 53 | void increment() const 54 | { 55 | Id++; 56 | } 57 | 58 | inline int get() const 59 | { 60 | return Id++; 61 | } 62 | 63 | private: 64 | mutable unsigned int Id = 0; 65 | }; 66 | 67 | int main() 68 | { 69 | Test tt = {}; 70 | tt.increment(); 71 | cout << tt.get() << endl; 72 | 73 | //capture by value 74 | int x = 1; 75 | auto f = [=]() mutable { x = 42; }; 76 | f(); 77 | cout << x << " - " << endl; 78 | 79 | return 0; 80 | } 81 | 82 | 83 | #+END_EXAMPLE 84 | 85 | 86 | *** Variadic Templates 87 | 88 | *Example from:* Modern C++ programming cookbook 89 | 90 | #+BEGIN_SRC C++ 91 | 92 | #include 93 | #include 94 | #include 95 | 96 | using namespace std; 97 | 98 | template < typename ... Ts > 99 | auto sum (Ts ... ts) 100 | { 101 | return (ts + ...); 102 | } 103 | 104 | template< typename R, typename ... Ts> 105 | auto matches( const R& range, Ts ... ts) 106 | { 107 | return (std::count(std::begin(range), std::end(range), ts) + ... ); 108 | } 109 | 110 | template 111 | bool within(T min, T max, Ts ... ts) 112 | { 113 | return ((min <= ts && ts <= max) && ...); 114 | } 115 | 116 | template 117 | void collapse_vectors(std::vector &vec, Ts ... ts) 118 | { 119 | (vec.push_back(ts), ...); 120 | } 121 | 122 | template 123 | void printline(T t) 124 | { 125 | cout << t ; 126 | } 127 | 128 | 129 | int main () 130 | { 131 | int the_sum { sum (1, 2, 3, 4, 5)}; 132 | cout << "Sum: " << the_sum << endl; 133 | 134 | string a {"Hello"}; 135 | string b {" World "}; 136 | cout << sum ( a, b ) << endl; 137 | 138 | vector v { 1,2,3,4,5}; 139 | cout << "Nr. of finds = " << matches(v, 2,5) << endl; 140 | 141 | 142 | cout << "is between = " << within(10, 20, 12, 15) << endl; 143 | cout << "is between = " << within(10, 20, 45, 55) << endl; 144 | 145 | std::vector vv {1,2,3}; 146 | collapse_vectors( vv, 5,6,8); 147 | for_each(vv.begin(), vv.end(), printline); 148 | } 149 | 150 | #+END_SRC 151 | 152 | *Another example:* [[https://github.com/NelsonBilber/cpp.variadic.templates][Source Code]] 153 | 154 | 155 | *** Move semantics 156 | 157 | [[https://github.com/NelsonBilber/cpp.movesemantics][Source Code]] 158 | 159 | 160 | *** Features by standard 161 | 162 | [[https://github.com/AnthonyCalandra/modern-cpp-features/blob/master/CPP11.md][C++11]] [[https://github.com/AnthonyCalandra/modern-cpp-features/blob/master/CPP14.md][C++14]] [[https://github.com/AnthonyCalandra/modern-cpp-features/blob/master/CPP17.md][C++17]] 163 | 164 | -------------------------------------------------------------------------------- /docs/multithreading.future.promises.org: -------------------------------------------------------------------------------- 1 | #+title: std::future and std::promises 2 | #+author: Nelson Bilber Rodrigues 3 | 4 | 5 | "... The class template std::future provides a mechanism to access the result of asynchronous operations: 6 | An asynchronous operation (created via std::async, std::packaged_task, or std::promise) can provide a 7 | std::future object to the creator of that asynchronous operation..." 8 | 9 | *Text and Source Code from:* 10 | https://en.cppreference.com/w/cpp/thread/future 11 | 12 | 13 | *** Futures vs. Promisses 14 | 15 | "... Future and Promise are the two separate sides of an asynchronous operation. 16 | (...) 17 | std::promise is used by the "producer/writer" of the asynchronous operation. 18 | std::future is used by the "consumer/reader" of the asynchronous operation. ..." 19 | (...) 20 | 21 | *Text and Source Code from:* 22 | https://stackoverflow.com/questions/12620186/futures-vs-promises 23 | 24 | 25 | *** When is it a good idea to use std::promise over the other std::thread mechanisms? 26 | 27 | (...) 28 | std::future is a strange beast: in general, you cannot modify its value directly. 29 | Three producers which can modify its value are: 30 | std::async through an asynchronous callback, which will return a std::future instance. 31 | std::packaged_task, which, when passed to a thread, will invoke its callback thereby updating the std::future instance associated with that std::packaged_task. This mechanism allows for early binding of a producer, but a later invocation. 32 | std::promise, which allows one to modify its associated std::future through its set_value() call. With this direct control over mutating a std::future, we must ensure that that the design is thread-safe if there are multiple producers (use std::mutex as necessitated). 33 | (...) 34 | 35 | *Text and Source Code from:* 36 | https://stackoverflow.com/questions/14283703/when-is-it-a-good-idea-to-use-stdpromise-over-the-other-stdthread-mechanisms 37 | 38 | 39 | *** What is std::promise? 40 | 41 | (...) 42 | In the words of [futures.state] a std::future is an asynchronous return object ("an object that reads results from a shared state") and a std::promise is an asynchronous provider ("an object that provides a result to a shared state") i.e. a promise is the thing that you set a result on, so that you can get it from the associated future. 43 | The asynchronous provider is what initially creates the shared state that a future refers to. std::promise is one type of asynchronous provider, std::packaged_task is another, and the internal detail of std::async is another. Each of those can create a shared state and give you a std::future that shares that state, and can make the state ready. 44 | std::async is a higher-level convenience utility that gives you an asynchronous result object and internally takes care of creating the asynchronous provider and making the shared state ready when the task completes. You could emulate it with a std::packaged_task (or std::bind and a std::promise) and a std::thread but it's safer and easier to use std::async. 45 | std::promise is a bit lower-level, for when you want to pass an asynchronous result to the future, but the code that makes the result ready cannot be wrapped up in a single function suitable for passing to std::async. For example, you might have an array of several promises and associated futures and have a single thread which does several calculations and sets a result on each promise. async would only allow you to return a single result, to return several you would need to call async several times, which might waste resources. 46 | (...) 47 | 48 | *Text and Source Code from:* 49 | https://stackoverflow.com/questions/11004273/what-is-stdpromise/12335206#12335206 50 | 51 | 52 | *** threads, promises, futures, async, C++ 53 | 54 | (...) 55 | std::future and std::promise 56 | Futures and promises are two sides of the same coin, so to speak. A promise allows us to return state from a thread. Whereas a future is for reading that returned state. 57 | std::async 58 | The example for the promise/future combination to create a producer consumer can be simplified further using the std::async which basically deals with creating a thread and creating a future for us. 59 | (...) 60 | 61 | *Text and Source Code from:* 62 | http://putridparrot.com/blog/threads-promises-futures-async-c/ 63 | 64 | 65 | *** Another nice reference: 66 | (...) 67 | Many times we encounter a situation where we want a thread to return a result. 68 | ... 69 | std::future is a class template and its object stores the future value. 70 | Now what the hell is this future value. 71 | Actually a std::future object internally stores a value that will be assigned in future and it also provides a mechanism to access that value i.e. using get() member function. But if somebody tries to access this associated value of future through get() function before it is available, then get() function will block till value is not available. 72 | std::promise is also a class template and its object promises to set the value in future. Each std::promise object has an associated std::future object that will give the value once set by the std::promise object. 73 | A std::promise object shares data with its associated std::future object. 74 | (...) 75 | 76 | 77 | *Text and Source Code from:* 78 | https://thispointer.com/c11-multithreading-part-8-stdfuture-stdpromise-and-returning-values-from-thread/ 79 | 80 | 81 | #+BEGIN_SRC C++ 82 | 83 | #include 84 | #include 85 | #include 86 | 87 | int main() 88 | { 89 | //future from a package task 90 | std::packaged_task task([]{return 7;}); //wrap the function 91 | //consumer 92 | std::future f1 = task.get_future(); //get a future 93 | std::thread t(std::move(task)); //lauch on a thread 94 | 95 | //future from an async() 96 | std::future f2 = std::async(std::launch::async, []{return 8;} ); 97 | 98 | // future from a promise 99 | std::promise p; 100 | std::future f3 = p.get_future(); 101 | std::thread( [&p]{ p.set_value_at_thread_exit(9); }).detach(); 102 | 103 | std::cout << "waiting" << std::flush; 104 | f1.wait(); 105 | f2.wait(); 106 | f3.wait(); 107 | std::cout << "Done!\nResults are: "<< f1.get() << ' ' << f2.get() << ' ' << f3.get() << '\n'; 108 | t.join(); 109 | 110 | /* Example 02 - ho to use a std::future and std::promisse*/ 111 | /* http://putridparrot.com/blog/threads-promises-futures-async-c/ */ 112 | auto promise = std::promise(); 113 | auto producer = std::thread([&] 114 | { 115 | std::cout << "Start Producer " <. 90 | - Iterator operations read from a container, but do not modify it, so they are thread-safe 91 | - Container operations that invalidate iterators are NOT thread-safe, as they modify the container 92 | - In general, common-sense concurrency rules apply. If you are modifying the container in multiple threads, you will need to protect that container to prevent concurrent access. 93 | 94 | 95 | * Iterators 96 | 97 | Text from book "C++ 17 STL Cookbook" 98 | 99 | ** Types of iterators 100 | 101 | *Input iterator* Input iterators can be dereferenced only for reading 102 | the values they point to. Once they are incremented, the last value they 103 | pointed to has been invalidated during the incrementation. This means 104 | that it is not possible to iterate over such a range multiple times. 105 | The std::istream_iterator is an example for this category. 106 | 107 | source code from: http://www.cplusplus.com/reference/iterator/istream_iterator/ 108 | 109 | #+BEGIN_SRC C++ 110 | 111 | // istream_iterator example 112 | #include // std::cin, std::cout 113 | #include // std::istream_iterator 114 | 115 | int main () 116 | { 117 | double value1, value2; 118 | std::cout << "Please, insert two values: "; 119 | 120 | std::istream_iterator eos; // end-of-stream iterator 121 | std::istream_iterator iit (std::cin); // stdin iterator 122 | 123 | if (iit!=eos) 124 | { 125 | value1=*iit; 126 | } 127 | ++iit; 128 | 129 | if (iit!=eos) 130 | { 131 | value2=*iit; 132 | } 133 | std::cout << value1 << "*" << value2 << "=" << (value1*value2) << '\n'; 134 | 135 | return 0; 136 | } 137 | 138 | #+END_SRC 139 | 140 | *Forward iterator* Forward iterators are the same as input iterators,but they differ in that regard that the ranges they represent can be 141 | iterated over multiple times. The  std::forward_list iterators are an example of that. Such a list can only be iterated over forward , not 142 | backward, but it can be iterated over as often as we like to. 143 | 144 | *Bidirectional iterator* The bidirectional iterator, as the name suggests, can be incremented and decremented, in order to iterate 145 | forward or backward. The iterators of std::list , std::set , and std::map , for example, support that. 146 | 147 | *Random access iterator* Random access iterators allow jumping over multiple values at once, instead of single-stepping. This is the case 148 | for iterators of std::vector and std::deque. 149 | 150 | *Contiguous iterator* This category specifies all of the aforementioned requirements, plus the requirement that the data that is being iterated 151 | through lies in contiguous memory, like it does in an array, or std::vector. 152 | 153 | *Output iterator* Output iterators are detached from the other categories. This is because an iterator can be a pure output iterator, 154 | which can only be incremented and used to write to the data it points to. If they are being read from, the value will be undefined. 155 | 156 | *Mutable iterator* If an iterator is an output iterator and one of the other categories at the same time, it is a mutable iterator. It can be 157 | read from and written to. If we obtain an iterator from a non-const container instance, it will usually be of this kind. 158 | 159 | *** Resume 160 | 161 | 162 | | Iterator Category | Ability | Providers | 163 | |-------------------+---------------------------------+----------------------------------------------------------| 164 | | Input iterator | Reads forward | istream | 165 | | Output iterator | Writes forward | ostream, inserter | 166 | | Forward iterator | Reads/writes forward | forward_list, unordered_[multi]set, unordered_[multi]map | 167 | | Bidirectional it. | Reads/writes forward/backward | list, [multi]set, [multi]map | 168 | | Random access it. | Reads/writes with random access | vector, deque string, array | 169 | | | | | 170 | 171 | 172 | *from source:* 173 | https://stackoverflow.com/questions/5211914/types-of-iterator-output-vs-input-vs-forward-vs-random-access-iterator 174 | 175 | 176 | ** Iterators Adapters 177 | 178 | *std::back_insert_iterator* The back_insert_iterator can be wrapped around std::vector , std::deque , std::list , and so on. It will call 179 | the container's push_back method, which inserts the new item past the existing items. If the container instance is not large enough, it will 180 | be grown automatically. 181 | 182 | *std::front_insert_iterator* The front_insert_iterator does exactly the same thing as back_insert_iterator , but it calls the container's 183 | push_front method, which inserts the new item before all the existing items. Note that for a container like std::vector , this means that all 184 | the existing items need to be moved one slot further in order to leave space for the new item at the front. 185 | 186 | *std::insert_iterator* This iterator adapter is similar to the other inserters, but is able to insert new items between existing ones. The 187 | std::inserter helper function which constructs such a wrapper takes two arguments. The first argument is the container and the second argument 188 | is an iterator that points to the position where new items shall be inserted. 189 | 190 | *std::istream_iterator* The istream_iterator is another very handy adapter. It can be used with any std::istream object (which can be the 191 | standard input or files for example and will try to parse the input from that stream object according to the template parameter it was 192 | instantiated with. In this advance how long the stream is. That leaves the question, where will the end iterator point to if we do not know 193 | where the stream's end is? The way this works is that the iterator knows when it reaches the end of the stream. When it is compared to the 194 | end iterator, it will effectively not really compare itself with the end iterator but return if the stream has any tokens left . That's why the 195 | end iterator constructor does not take any arguments. 196 | 197 | *std::ostream_iterator* The ostream_iterator is the same thing as the istream_iterator , but it works the other way around: It doesn't take 198 | tokens from an input stream--it pushes tokens into an output stream. Another difference to istream_iterator is that its constructor takes a 199 | second argument, which is a string that shall be pushed into the output stream after each item. That is useful because this way we can print a 200 | separating "," or a new line after each item. 201 | 202 | 203 | * When to use it ? 204 | 205 | *** Nice Flowchart !!! 206 | 207 | #+CAPTION: STL logo 208 | #+NAME: STL 209 | #+ATTR_HTML: :style margin-left: auto; margin-right: auto; 210 | [[../imgs/stl.png]] 211 | 212 | https://stackoverflow.com/questions/471432/in-which-scenario-do-i-use-a-particular-stl-container 213 | 214 | *** Complexity Big-Oh 215 | 216 | [[https://stackoverflow.com/questions/181693/what-are-the-complexity-guarantees-of-the-standard-containers][What are the complexity guarantees of the standard containers?]] 217 | 218 | [[http://john-ahlgren.blogspot.com/2013/10/stl-container-performance.html][STL Container Performance]] 219 | 220 | *** Scott Meyers 221 | Look at Effective STL by Scott Meyers. It's good at explaining how to use the STL. 222 | 223 | If you want to store a determined/undetermined number of objects and you're never going to delete any, then a vector is what you want. It's the default replacement for a C array, and it works like one, but doesn't overflow. You can set its size beforehand as well with reserve(). 224 | 225 | If you want to store an undetermined number of objects, but you'll be adding them and deleting them, then you probably want a list...because you can delete an element without moving any following elements - unlike vector. It takes more memory than a vector, though, and you can't sequentially access an element. 226 | 227 | If you want to take a bunch of elements and find only the unique values of those elements, reading them all into a set will do it, and it will sort them for you as well. 228 | 229 | If you have a lot of key-value pairs, and you want to sort them by key, then a map is useful...but it will only hold one value per key. If you need more than one value per key, you could have a vector/list as your value in the map, or use a multimap. 230 | 231 | It's not in the STL, but it is in the TR1 update to the STL: if you have a lot of key-value pairs that you're going to look up by key, and you don't care about their order, you might want to use a hash - which is tr1::unordered_map. I've used it with Visual C++ 7.1, where it was called stdext::hash_map. It has a lookup of O(1) instead of a lookup of O(log n) for map. 232 | 233 | *** Stack overflow 234 | 235 | It all depends on what you want to store and what you want to do with the container. Here are some (very non-exhaustive) examples for the container classes that I tend to use most: 236 | vector: Compact layout with little or no memory overhead per contained object. Efficient to iterate over. Append, insert and erase can be expensive, particularly for complex objects. Cheap to find a contained object by index, e.g. myVector[10]. Use where you would have used an array in C. Good where you have a lot of simple objects (e.g. int). Don't forget to use reserve() before adding a lot of objects to the container. 237 | list: Small memory overhead per contained object. Efficient to iterate over. Append, insert and erase are cheap. Use where you would have used a linked list in C. 238 | set (and multiset): Significant memory overhead per contained object. Use where you need to find out quickly if that container contains a given object, or merge containers efficiently. 239 | map (and multimap): Significant memory overhead per contained object. Use where you want to store key-value pairs and look up values by key quickly. 240 | The flow chart on the cheat sheet suggested by zdan provides a more exhaustive guide. 241 | 242 | *** SGI 243 | 244 | http://www.sgi.com/tech/stl/complexity.html 245 | http://www.sgi.com/tech/stl/table_of_contents.html 246 | 247 | Fundamentally, it is difficult to define the notion of asymptotic algorithm complexity precisely for real computer hardware instead of an abstract machine model. Thus we settle for the following guidelines: 248 | 249 | For an algorithm A to have running time O(f(n)), there must be a corresponding algorithm A' that is correct on machines with arbitrarily long pointer and size_t types, such that A and A' perform essentially the same sequence of operations on the actual hardware. (In simple cases A and A' will be the same. In other cases A may have been simplified with the knowledge that adresses are bounded.) For inputs of sufficiently large size n, A' must take at most time Cf(n), where C is a constant, independent of both n and the address size. (Pointer, size_t, and ptrdiff_t operations are presumed to take constant time independent of their size.) 250 | All container or iterator complexity specifications refer to amortized complexity. An individual operation may take longer than specified. But any sufficiently long sequence of operations on the same container or iterator will take at most as long as the corresponding sum of the specified operation costs. 251 | Algorithms specify either worst-case or average case performance, and identify which. Unless otherwise stated, averages assume that container elements are chosen from a finite type with more possible values than the size of the container, and that container elements are independently uniformly distributed. 252 | A complexity specification for an operation f assumes that operations invoked by f require at most the specified runtime. But algorithms generally remain appropriate if the invoked operations are no more than a logarithmic factor slower than specified in the expected case. 253 | If operations are more expensive than assumed by a function F in the current STL, then F will slow down at most in proportion to the added cost. Any future operations that fail to satisfy this property will make that explicit. 254 | 255 | To make this precise, assume F is specified to use time f(m) for input of size m. F uses operations Gk, with specified running times gk(n) on input size n. If F is used in a context in which each Gk is slower than expected by at most a factor h(n), then F slows down by at most a factor h(m). This holds because none of the current algorithms ever apply the operations Gk to inputs significantly larger than m. 256 | 257 | 258 | http://www.cs.northwestern.edu/~riesbeck/programming/c++/stl-summary.html 259 | 260 | http://landenlabs.com/code/perf-stl/perf-stl.html 261 | 262 | https://baptiste-wicht.com/posts/2012/12/cpp-benchmark-vector-list-deque.html 263 | 264 | 265 | *** General Rules of Thumb 266 | 267 | **** Use sequential containers when you need to access elements by position 268 | - Use std:vector as your default sequential container, especially as an alternative to built-in arrays 269 | - If size is known in advance, use std::array instead of a built-in array 270 | - If you add or remove elements frequently at both the front and back of a container, use std::deque 271 | - Use a std::list (not std::deque) if you need to insert/remove elements in the middle of the sequence 272 | - Do not use std::list if you need random access to objects 273 | - Prefer std::vector over std::list if your system uses a cache 274 | - std::string is almost always better than a C-string 275 | 276 | **** Use associative containers when you need to access elements by key 277 | - For key/value pair, default to std::unordered_map, or if element order matters, std::map 278 | - If you need multiple entries for the same key, use std::unordered_multimap, or if element order matters, std::multimap 279 | 280 | **** Memory allocation may also be a factor in your decision. Here are the general rules of thumb for how the different sequential containers are storing memory: 281 | - std:vector, std::array, and std::string store memory contiguously and are compatible with C-style APIs 282 | - std::deque allocates memory in chunks 283 | - std::list allocates memory by node 284 | 285 | 286 | * Important Notes 287 | 288 | *** Vector should be used by default as the (sequence) container: 289 | 290 | - It is more (space and time) efficient than other STL containers. 291 | - It is more convenient and safer than primitive array. 292 | - automatic memory management 293 | - rich interface 294 | 295 | 296 | *** Associative containers properties 297 | 298 | The underlying data structure is a balanced search tree: 299 | - logarithmic access time 300 | - requires order comparisons of keys 301 | - iteration in key order 302 | - Iterators, pointers and references stay valid until the pointed to element is removed. 303 | 304 | 305 | 306 | * Cheat Sheet 307 | 308 | [[http://homepages.e3.net.nz/~djm/cppcontainers.html][C++ Containers Cheat Sheet]] 309 | 310 | [[http://homepages.e3.net.nz/~djm/cppiterators.html][C++ Iterators & Algorithms Cheat Shee]]t 311 | 312 | 313 | * Links and References 314 | 315 | https://www.cs.helsinki.fi/u/tpkarkka/alglib/k06/lectures/containers.html 316 | 317 | https://arne-mertz.de/2018/05/modern-c-features-stdvariant-and-stdvisit/ 318 | --------------------------------------------------------------------------------