From cc054bb24b403e30ddebf17c9d3cefe5fce8c62a Mon Sep 17 00:00:00 2001 From: Kamran Ahmed Date: Thu, 1 Jun 2023 03:18:40 +0100 Subject: [PATCH] Add content to C++ roadmap --- scripts/roadmap-content.cjs | 4 +- .../100-introduction/100-what-is-cpp.md | 46 +++++++++- .../content/100-introduction/101-why-cpp.md | 64 +++++++++++++- .../content/100-introduction/102-c-vs-cpp.md | 72 ++++++++++++++- .../content/101-setting-up/100-installing.md | 50 ++++++++++- .../101-setting-up/101-code-editors.md | 14 ++- .../100-arithmetic-operators.md | 67 +++++++++++++- .../101-logical-operators.md | 56 +++++++++++- .../content/102-basic-operations/102-loops.md | 88 ++++++++++++++++++- .../cpp/content/103-functions/100-lambda.md | 63 ++++++++++++- .../104-data-types/100-static-typing.md | 26 +++++- .../101-dynamic-typing/100-rtti.md | 71 ++++++++++++++- .../101-dynamic-typing/index.md | 61 ++++++++++++- .../100-references.md | 40 ++++++++- .../101-memory-model/100-object-lifetime.md | 41 ++++++++- .../105-pointers-and-references/index.md | 42 ++++++++- .../raw-pointers/100-new-delete-operators.md | 48 +++++++++- .../raw-pointers/101-memory-leakage.md | 29 +++++- .../smart-pointers/100-weak-ptr.md | 49 ++++++++++- .../smart-pointers/101-shared-ptr.md | 51 ++++++++++- .../smart-pointers/102-uniqe-ptr.md | 67 +++++++++++++- .../100-scope/index.md | 71 ++++++++++++++- .../100-forward-declaration.md | 48 +++++++++- .../101-oop/100-static-polymorphism/index.md | 60 ++++++++++++- .../overloading-functions.md | 47 +++++++++- .../101-oop/101-dynamic-polymorphism/index.md | 67 +++++++++++++- .../virtual-methods.md | 66 +++++++++++++- .../virtual-tables.md | 52 ++++++++++- .../100-diamond-inheritance.md | 54 +++++++++++- .../107-structures-and-classes/index.md | 66 +++++++++++++- .../100-exceptions/index.md | 51 ++++++++++- .../108-exception-handling/101-exit-codes.md | 60 ++++++++++++- .../content/109-language-concepts/100-auto.md | 50 ++++++++++- .../101-type-casting/100-static-cast.md | 41 ++++++++- .../101-type-casting/101-const-cast.md | 33 ++++++- .../101-type-casting/102-dynamic-cast.md | 41 ++++++++- .../101-type-casting/103-reinterpret-cast.md | 31 ++++++- .../101-type-casting/index.md | 45 +++++++++- .../102-undefined-behavior.md | 40 ++++++++- .../content/109-language-concepts/103-adl.md | 33 ++++++- .../104-name-mangling.md | 28 +++++- .../109-language-concepts/105-macros.md | 56 +++++++++++- .../cpp/content/110-stl/101-iostream.md | 49 ++++++++++- .../cpp/content/110-stl/104-multithreading.md | 78 +++++++++++++++- .../111-templates/100-variadic-templates.md | 72 ++++++++++++++- .../101-template-specialization/100-full.md | 47 +++++++++- .../101-partial.md | 60 ++++++++++++- .../content/111-templates/102-type-traits.md | 58 +++++++++++- .../cpp/content/111-templates/103-finae.md | 37 +++++++- .../cpp/content/111-templates/index.md | 77 +++++++++++++++- .../cpp/content/112-idioms/100-raii.md | 74 +++++++++++++++- .../cpp/content/112-idioms/101-pimpl.md | 50 ++++++++++- .../cpp/content/112-idioms/102-crtp.md | 49 ++++++++++- .../content/112-idioms/103-non-copyable.md | 32 ++++++- .../content/112-idioms/104-erase-remove.md | 37 +++++++- .../cpp/content/112-idioms/105-copy-swap.md | 38 +++++++- .../cpp/content/112-idioms/106-copy-write.md | 44 +++++++++- .../cpp/content/113-standards/101-cpp17.md | 62 ++++++++++++- .../cpp/content/113-standards/104-cpp0x.md | 75 +++++++++++++++- .../114-debuggers/101-debugger-symbols.md | 44 +++++++++- .../cpp/content/114-debuggers/103-gdb.md | 82 ++++++++++++++++- .../content/116-build-systems/100-cmake.md | 60 ++++++++++++- .../content/116-build-systems/101-makefile.md | 56 +++++++++++- .../content/116-build-systems/102-ninja.md | 35 +++++++- .../content/117-package-managers/100-vcpkg.md | 66 +++++++++++++- .../content/117-package-managers/101-spack.md | 59 ++++++++++++- .../content/117-package-managers/102-conan.md | 80 ++++++++++++++++- .../content/117-package-managers/103-nuget.md | 46 +++++++++- .../cpp/content/117-package-managers/index.md | 51 ++++++++++- .../118-working-with-libs/100-inclusion.md | 38 +++++++- .../118-working-with-libs/101-licensing.md | 40 ++++++++- .../roadmaps/cpp/content/frameworks/101-qt.md | 38 +++++++- .../content/frameworks/103-orbit-profiler.md | 70 ++++++++++++++- .../cpp/content/libraries/100-boost.md | 46 +++++++++- .../cpp/content/libraries/101-open-cv.md | 58 +++++++++++- .../cpp/content/libraries/102-poco.md | 72 ++++++++++++++- .../cpp/content/libraries/105-tensorflow.md | 54 +++++++++++- .../cpp/content/libraries/107-spdlog.md | 60 ++++++++++++- .../roadmaps/cpp/content/libraries/109-fmt.md | 70 ++++++++++++++- 79 files changed, 4073 insertions(+), 80 deletions(-) diff --git a/scripts/roadmap-content.cjs b/scripts/roadmap-content.cjs index 04ebe2f99..c31ead944 100644 --- a/scripts/roadmap-content.cjs +++ b/scripts/roadmap-content.cjs @@ -61,9 +61,9 @@ function writeTopicContent(currTopicUrl) { const roadmapTitle = roadmapId.replace(/-/g, ' '); - let prompt = `I am reading a guide about "${roadmapTitle}". I am on the topic "${parentTopic}". I want to know more about "${childTopic}". Write me a brief summary for that topic. Content should be in markdown. Behave as if you are the author of the guide.`; + let prompt = `I am reading a guide about "${roadmapTitle}". I am on the topic "${parentTopic}". I want to know more about "${childTopic}". Write me with a brief summary of that. Content should be in markdown. I already know the benefits of each so do not add benefits in the output. Also include the code examples if applicable to this topic.`; if (!childTopic) { - prompt = `I am reading a guide about "${roadmapTitle}". I am on the topic "${parentTopic}". I want to know more about "${parentTopic}". Write me a brief summary for that topic. Content should be in markdown. Behave as if you are the author of the guide.`; + prompt = `I am reading a guide about "${roadmapTitle}". I am on the topic "${parentTopic}". I want to know more about "${parentTopic}". Write me with a brief summary of that. Content should be in markdown. I already know the benefits of each so do not add benefits in the output. Also include the code examples if applicable to this topic.`; } console.log(`Generating '${childTopic || parentTopic}'...`); diff --git a/src/data/roadmaps/cpp/content/100-introduction/100-what-is-cpp.md b/src/data/roadmaps/cpp/content/100-introduction/100-what-is-cpp.md index 0a370ae1c..c2d6694eb 100644 --- a/src/data/roadmaps/cpp/content/100-introduction/100-what-is-cpp.md +++ b/src/data/roadmaps/cpp/content/100-introduction/100-what-is-cpp.md @@ -1 +1,45 @@ -# What is cpp \ No newline at end of file +# What is C++? +C++ is a general-purpose programming language created by Bjarne Stroustrup as an extension of the C programming language. It was first introduced in 1985 and provides object-oriented features like classes and inheritance. C++ is widely used in various applications like game development, system programming, embedded systems, and high-performance computing. + +C++ is a statically-typed language, meaning that the type of a variable is determined during compilation, and has an extensive library called the C++ Standard Library, which provides a rich set of functions, algorithms, and data structures for various tasks. + +C++ builds upon the features of C, and thus, most C programs can be compiled and run with a C++ compiler. + +## Code Example + +Here's a simple example of a C++ program that demonstrates some essential features of the language: + +```cpp +#include + +// A simple function to add two numbers +int add(int a, int b) { + return a + b; +} + +class Calculator { +public: + // A member function to multiply two numbers + int multiply(int a, int b) { + return a * b; + } +}; + +int main() { + int x = 5; + int y = 3; + + // Using the standalone function 'add' + int sum = add(x, y); + std::cout << "Sum: " << sum << std::endl; + + // Using a class and member function + Calculator calc; + int product = calc.multiply(x, y); + std::cout << "Product: " << product << std::endl; + + return 0; +} +``` + +In the above program, we define a simple function `add` and a class `Calculator` with a member function `multiply`. The `main` function demonstrates how to use these to perform basic arithmetic. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/100-introduction/101-why-cpp.md b/src/data/roadmaps/cpp/content/100-introduction/101-why-cpp.md index c968fea43..a748cb5c1 100644 --- a/src/data/roadmaps/cpp/content/100-introduction/101-why-cpp.md +++ b/src/data/roadmaps/cpp/content/100-introduction/101-why-cpp.md @@ -1 +1,63 @@ -# Why cpp \ No newline at end of file +# Why C++ +C++ is a popular and widely used programming language for various reasons. Here are some of the reasons why you might choose to utilize C++: + +## Performance + +C++ is designed to provide high performance and efficiency. It offers fine-grained control over system resources, making it easier to optimize your software. + +## Portability + +C++ is supported on different computer architectures and operating systems, allowing you to write portable code that runs on various platforms without making major modifications. + +## Object-Oriented Programming + +C++ supports object-oriented programming (OOP) - a paradigm that allows you to design programs using classes and objects, leading to better code organization and reusability. + +```cpp +class MyClass { + public: + void myFunction() { + // Code here + } +}; + +int main() { + MyClass obj; + obj.myFunction(); +} +``` + +## Support for low-level and high-level programming + +C++ allows you to write both low-level code, like memory manipulation, as well as high-level abstractions, like creating classes and using the Standard Template Library (STL). + +```cpp +#include +#include + +int main() { + // Low-level programming + int number = 42; + int* ptr_number = &number; + + // High-level programming + std::vector myVector = {1, 2, 3}; + for(const auto &i: myVector) { + std::cout << i << std::endl; + } +} +``` + +## Extensive Libraries + +C++ offers a vast range of libraries and tools, such as the Standard Template Library (STL), Boost, and Qt, among others, that can aid in the development of your projects and make it more efficient. + +## Combination with C language + +C++ can be combined with C, offering the capabilities of both languages and allowing you to reuse your existing C code. By incorporating C++ features, you can enhance your code and improve its functionality. + +## Active Community + +C++ has been around for a long time and has a large, active community of users who contribute to the growth of the language, express new ideas, and engage in discussions that help develop the language further. This makes finding solutions to any problems you experience much easier. + +In summary, C++ offers a great balance of performance, portability, and feature set, making it a versatile and powerful programming language suitable for many applications. With its extensive libraries, active community, and continuous development, C++ is an excellent choice for any software development project. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/100-introduction/102-c-vs-cpp.md b/src/data/roadmaps/cpp/content/100-introduction/102-c-vs-cpp.md index 8e02b5415..c1d6ba74e 100644 --- a/src/data/roadmaps/cpp/content/100-introduction/102-c-vs-cpp.md +++ b/src/data/roadmaps/cpp/content/100-introduction/102-c-vs-cpp.md @@ -1 +1,71 @@ -# C vs cpp \ No newline at end of file +# C vs C++ +C and C++ are two popular programming languages with some similarities, but they also have key differences. C++ is an extension of the C programming language, with added features such as object-oriented programming, classes, and exception handling. Although both languages are used for similar tasks, they have their own syntax and semantics, which makes them distinct from each other. + +### Syntax and Semantics + +#### C +- C is a procedural programming language. +- Focuses on functions and structured programming. +- Does not support objects or classes. +- Memory management is manual, using functions like `malloc` and `free`. + +```c +#include + +void printHello() { + printf("Hello, World!\n"); +} + +int main() { + printHello(); + return 0; +} +``` + +#### C++ +- C++ is both procedural and object-oriented. +- Supports both functions and classes. +- Incorporates different programming paradigms. +- Memory management can be manual (like C) or rely on constructors/destructors and smart pointers. + +```cpp +#include + +class HelloWorld { +public: + void printHello() { + std::cout << "Hello, World!" << std::endl; + } +}; + +int main() { + HelloWorld obj; + obj.printHello(); + return 0; +} +``` + +### Code Reusability and Modularity + +#### C +- Code reusability is achieved through functions and modular programming. +- High cohesion and low coupling are achieved via structured design. +- Function libraries can be created and included through headers. + +#### C++ +- Offers better code reusability with classes, inheritance, and polymorphism. +- Code modularity is enhanced through namespaces and well-designed object-oriented hierarchy. + +### Error Handling + +#### C +- Error handling in C is done primarily through return codes. +- Lacks support for exceptions or any built-in error handling mechanism. + +#### C++ +- Offers exception handling, which can be used to handle errors that may occur during program execution. +- Enables catching and handling exceptions with `try`, `catch`, and `throw` keywords, providing more control over error handling. + +### Conclusion + +Both C and C++ are powerful languages with unique features and capabilities. While C is simpler and focuses on procedural programming, C++ offers the versatility of using different programming paradigms and improved code organization. Understanding the differences between these two languages can help you decide which one is more suitable for your specific needs and programming style. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/101-setting-up/100-installing.md b/src/data/roadmaps/cpp/content/101-setting-up/100-installing.md index 35e288c68..f084871c0 100644 --- a/src/data/roadmaps/cpp/content/101-setting-up/100-installing.md +++ b/src/data/roadmaps/cpp/content/101-setting-up/100-installing.md @@ -1 +1,49 @@ -# Installing \ No newline at end of file +# Installing C++ +Before you can start programming in C++, you will need to have a compiler installed on your system. A compiler is a program that converts the C++ code you write into an executable file that your computer can run. There are several popular C++ compilers to choose from, depending on your operating system and preference. + +#### Windows +For Windows, one popular option is to install the [Microsoft Visual Studio IDE](https://visualstudio.microsoft.com/vs/), which includes the Microsoft Visual C++ compiler. + +Alternatively, you can also install the [MinGW-w64](https://mingw-w64.org/doku.php) compiler, which is a Windows port of the GNU Compiler Collection (GCC). To install MinGW-w64, follow these steps: + +1. Download the installer from [here](https://sourceforge.net/projects/mingw-w64/files/). +2. Run the installer and select your desired architecture, version, and install location. +3. Add the `bin` folder inside the installation directory to your system's `PATH` environment variable. + +#### macOS +For macOS, you can install the Apple LLVM `clang` compiler which is part of the Xcode Command Line Tools. To do this, open a terminal and enter: + +``` +xcode-select --install +``` + +This will prompt a dialog to install the Command Line Tools, which includes the `clang` compiler. + +#### Linux +On Linux, you can install the GNU Compiler Collection (GCC) through your distribution's package manager. Here are some examples for popular Linux distributions: + +- Ubuntu, Debian, and derivatives: +``` +sudo apt-get install g++ build-essential +``` + +- Fedora, CentOS, RHEL, and derivatives: +``` +sudo dnf install gcc-c++ make +``` + +- Arch Linux and derivatives: +``` +sudo pacman -S gcc make +``` + +#### Checking the Installation +To confirm that the compiler is installed and available on your system, open a terminal/command prompt, and enter the following command: + +``` +g++ --version +``` + +You should see output displaying the version of your installed C++ compiler. + +Now you're ready to start writing and compiling your C++ code! \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/101-setting-up/101-code-editors.md b/src/data/roadmaps/cpp/content/101-setting-up/101-code-editors.md index 9ebea51d6..f72ad50d0 100644 --- a/src/data/roadmaps/cpp/content/101-setting-up/101-code-editors.md +++ b/src/data/roadmaps/cpp/content/101-setting-up/101-code-editors.md @@ -1 +1,13 @@ -# Code editors \ No newline at end of file +# Code Editors + +Code editors are programs specifically designed for editing, managing and writing source code. They offer a wide range of features that make the development process easier and faster. Here's a brief introduction to some of the most popular code editors for C++: + +1. **Visual Studio Code (VSCode)**: Visual Studio Code is a popular, free, open-source, and lightweight code editor developed by Microsoft. It has built-in support for C++, along with an extensive library of extensions and plugins. + +2. **Sublime Text**: Sublime Text is a cross-platform text editor that is quite popular among developers due to its speed and minimalist design. It supports C++ with the help of plugins and has a variety of themes and packages available for customization. + +3. **CLion**: CLion is an Integrated Development Environment (IDE) developed by JetBrains specifically for C and C++ developers. It provides advanced features like code completion, refactoring support, debugging, and more. + +These are just a few examples, and there are many other code editors available, including Atom, Notepad++, and Geany. They all have their features and may suit different developers' needs. Finding the right code editor is often a matter of personal preference and workflow. + +To work with C++ in your chosen code editor, you often need to install some additional tools and add-ons, such as compilers, linters, and debugger support. Make sure to follow the instructions provided by the editor's documentation to set up C++ correctly. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/102-basic-operations/100-arithmetic-operators.md b/src/data/roadmaps/cpp/content/102-basic-operations/100-arithmetic-operators.md index 461e9fd10..588d79c60 100644 --- a/src/data/roadmaps/cpp/content/102-basic-operations/100-arithmetic-operators.md +++ b/src/data/roadmaps/cpp/content/102-basic-operations/100-arithmetic-operators.md @@ -1 +1,66 @@ -# Arithmetic operators \ No newline at end of file +# Arithmetic Operators in C++ + +Arithmetic operators are used to perform mathematical operations with basic variables such as integers and floating-point numbers. Here is a brief summary of the different arithmetic operators in C++: + +## 1. Addition Operator (`+`) + +It adds two numbers together. + +```cpp +int sum = a + b; +``` + +## 2. Subtraction Operator (`-`) + +It subtracts one number from another. + +```cpp +int difference = a - b; +``` + +## 3. Multiplication Operator (`*`) + +It multiplies two numbers together. + +```cpp +int product = a * b; +``` + +## 4. Division Operator (`/`) + +It divides one number by another. Note that if both operands are integers, it will perform integer division and the result will be an integer. + +```cpp +int quotient = a / b; // integer division +float quotient = float(a) / float(b); // floating-point division +``` + +## 5. Modulus Operator (`%`) + +It calculates the remainder of an integer division. + +```cpp +int remainder = a % b; +``` + +## 6. Increment Operator (`++`) + +It increments the value of a variable by 1. There are two ways to use this operator: prefix (`++x`) and postfix (`x++`). Prefix increments the value before returning it, whereas postfix returns the value first and then increments it. + +```cpp +int x = 5; +int y = ++x; // x = 6, y = 6 +int z = x++; // x = 7, z = 6 +``` + +## 7. Decrement Operator (`--`) + +It decrements the value of a variable by 1. It can also be used in prefix (`--x`) and postfix (`x--`) forms. + +```cpp +int x = 5; +int y = --x; // x = 4, y = 4 +int z = x--; // x = 3, z = 4 +``` + +These are the basic arithmetic operators in C++ that allow you to perform mathematical operations on your variables. Use them in combination with other control structures, such as loops and conditionals, to build more complex programs. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/102-basic-operations/101-logical-operators.md b/src/data/roadmaps/cpp/content/102-basic-operations/101-logical-operators.md index 9e376cd3e..efcff6505 100644 --- a/src/data/roadmaps/cpp/content/102-basic-operations/101-logical-operators.md +++ b/src/data/roadmaps/cpp/content/102-basic-operations/101-logical-operators.md @@ -1 +1,55 @@ -# Logical operators \ No newline at end of file +# Logical Operators in C++ + +Logical operators are used to perform logical operations on the given expressions, mostly to test the relationship between different variables or values. They return a boolean value i.e., either true (1) or false (0) based on the result of the evaluation. + +C++ provides the following logical operators: + +1. **AND Operator (&&)** + The AND operator checks if both the operands/conditions are true, then the expression is true. If any one of the conditions is false, the whole expression will be false. + ``` + (expression1 && expression2) + ``` + Example: + ```cpp + int a = 5, b = 10; + if (a > 0 && b > 0) { + cout << "Both values are positive." << endl; + } + ``` +2. **OR Operator (||)** + The OR operator checks if either of the operands/conditions are true, then the expression is true. If both the conditions are false, it will be false. + ``` + (expression1 || expression2) + ``` + Example: + ```cpp + int a = 5, b = -10; + if (a > 0 || b > 0) { + cout << "At least one value is positive." << endl; + } + ``` + +3. **NOT Operator (!)** + The NOT operator reverses the result of the condition/expression it is applied on. If the condition is true, the NOT operator will make it false and vice versa. + ``` + !(expression) + ``` + Example: + ```cpp + int a = 5; + if (!(a < 0)) { + cout << "The value is not negative." << endl; + } + ``` + +Using these operators, you can create more complex logical expressions, for example: + +```cpp +int a = 5, b = -10, c = 15; + +if (a > 0 && (b > 0 || c > 0)) { + cout << "At least two values are positive." << endl; +} +``` + +This covers the essential information about logical operators in C++. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/102-basic-operations/102-loops.md b/src/data/roadmaps/cpp/content/102-basic-operations/102-loops.md index d31a16aa6..729246627 100644 --- a/src/data/roadmaps/cpp/content/102-basic-operations/102-loops.md +++ b/src/data/roadmaps/cpp/content/102-basic-operations/102-loops.md @@ -1 +1,87 @@ -# Loops \ No newline at end of file +# Loops in C++ + +Loops are an essential concept in programming that allow you to execute a block of code repeatedly until a specific condition is met. In C++, there are three main types of loops: `for`, `while`, and `do-while`. + +## For Loop + +A `for` loop is used when you know the number of times you want to traverse through a block of code. It consists of an initialization statement, a condition, and an increment/decrement operation. + +Here's the syntax for a `for` loop: + +```cpp +for (initialization; condition; increment/decrement) { + // block of code to execute +} +``` + +For example: + +```cpp +#include +using namespace std; + +int main() { + for (int i = 0; i < 5; i++) { + cout << "Iteration: " << i << endl; + } + return 0; +} +``` + +## While Loop + +A `while` loop runs as long as a specified condition is `true`. The loop checks for the condition before entering the body of the loop. + +Here's the syntax for a `while` loop: + +```cpp +while (condition) { + // block of code to execute +} +``` + +For example: + +```cpp +#include +using namespace std; + +int main() { + int i = 0; + while (i < 5) { + cout << "Iteration: " << i << endl; + i++; + } + return 0; +} +``` + +## Do-While Loop + +A `do-while` loop is similar to a `while` loop, with the key difference being that the loop body is executed at least once, even when the condition is `false`. + +Here's the syntax for a `do-while` loop: + +```cpp +do { + // block of code to execute +} while (condition); +``` + +For example: + +```cpp +#include +using namespace std; + +int main() { + int i = 0; + do { + cout << "Iteration: " << i << endl; + i++; + } while (i < 5); + return 0; +} +``` + +In summary, loops are an integral part of C++ programming that allow you to execute a block of code multiple times. The three types of loops in C++ are `for`, `while`, and `do-while`. Each type has its own specific use case and can be chosen depending on the desired behavior. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/103-functions/100-lambda.md b/src/data/roadmaps/cpp/content/103-functions/100-lambda.md index e5c92562f..7a424586b 100644 --- a/src/data/roadmaps/cpp/content/103-functions/100-lambda.md +++ b/src/data/roadmaps/cpp/content/103-functions/100-lambda.md @@ -1 +1,62 @@ -# Lambda \ No newline at end of file +# Lambda Functions in C++ + +A lambda function, or simply "lambda", is an anonymous (unnamed) function that is defined in place, within your source code, and with a concise syntax. Lambda functions were introduced in C++11 and have since become a widely used feature, especially in combination with the Standard Library algorithms. + +## Syntax + +Here is a basic syntax of a lambda function in C++: + +```cpp +[capture-list](parameters) -> return_type { + // function body +}; +``` + +- **capture-list**: A list of variables from the surrounding scope that the lambda function can access. +- **parameters**: The list of input parameters, just like in a regular function. Optional. +- **return_type**: The type of the value that the lambda function will return. This part is optional, and the compiler can deduce it in many cases. +- **function body**: The code that defines the operation of the lambda function. + +## Usage Examples + +Here are a few examples to demonstrate the use of lambda functions in C++: + +1. Lambda function with no capture, parameters, or return type. + +```cpp +auto printHello = []() { + std::cout << "Hello, World!" << std::endl; +}; +printHello(); // Output: Hello, World! +``` + +2. Lambda function with parameters. + +```cpp +auto add = [](int a, int b) { + return a + b; +}; +int result = add(3, 4); // result = 7 +``` + +3. Lambda function with capture-by-value. + +```cpp +int multiplier = 3; +auto times = [multiplier](int a) { + return a * multiplier; +}; +int result = times(5); // result = 15 +``` + +4. Lambda function with capture-by-reference. + +```cpp +int expiresInDays = 45; +auto updateDays = [&expiresInDays](int newDays) { + expiresInDays = newDays; +}; +updateDays(30); // expiresInDays = 30 +``` + +Note that, when using the capture by reference, any change made to the captured variable *inside* the lambda function will affect its value in the surrounding scope. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/104-data-types/100-static-typing.md b/src/data/roadmaps/cpp/content/104-data-types/100-static-typing.md index 1d2fe98dd..0b902d9b3 100644 --- a/src/data/roadmaps/cpp/content/104-data-types/100-static-typing.md +++ b/src/data/roadmaps/cpp/content/104-data-types/100-static-typing.md @@ -1 +1,25 @@ -# Static typing \ No newline at end of file +# Static Typing + +In C++, static typing means that the data type of a variable is determined at compile time, before the program is executed. This means that a variable can be used only with data of a specific type, and the compiler ensures that the operations performed with the variable are compatible with its type. + +C++ is a statically typed language, which means that it uses static typing to determine data types and perform type checking during compile time. This helps with ensuring type safety and can prevent certain types of errors from occurring during the execution of the program. + +Here's a simple code example to demonstrate static typing in C++: + +```cpp +#include + +int main() { + int num = 42; // 'num' is statically typed as an integer + double pi = 3.14159; // 'pi' is statically typed as a double + + num = pi; // This assignment would cause a compile-time error as the types don't match + + std::cout << "The value of num is: " << num << std::endl; + std::cout << "The value of pi is: " << pi << std::endl; + + return 0; +} +``` + +In the code above, the variable `num` is statically typed as an `int`, and `pi` is statically typed as a `double`. If you attempt to assign the value of `pi` to `num`, you'll get a compile-time error. This is because the static typing system ensures that variables are only used with compatible data types. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/104-data-types/101-dynamic-typing/100-rtti.md b/src/data/roadmaps/cpp/content/104-data-types/101-dynamic-typing/100-rtti.md index 9a084f554..568c1f279 100644 --- a/src/data/roadmaps/cpp/content/104-data-types/101-dynamic-typing/100-rtti.md +++ b/src/data/roadmaps/cpp/content/104-data-types/101-dynamic-typing/100-rtti.md @@ -1 +1,70 @@ -# Rtti \ No newline at end of file +# Run-Time Type Identification (RTTI) + +Run-Time Type Identification (RTTI) is a feature in C++ that allows you to obtain the type information of an object during program execution. This can be useful when using dynamic typing, where the type of an object can change at runtime. + +There are two main mechanisms for RTTI in C++: + +1. `typeid` operator +2. `dynamic_cast` operator + +### 1. typeid operator + +`typeid` is an operator that returns a reference to an object of type `std::type_info`, which contains information about the type of the object. The header file `` should be included to use `typeid`. + +Here is an example: +```cpp +#include +#include + +class Base { virtual void dummy() {} }; +class Derived : public Base { /* ... */ }; + +int main() { + Base* base_ptr = new Derived; + + // Using typeid to get the type of the object + std::cout << "Type: " << typeid(*base_ptr).name() << '\n'; + + delete base_ptr; + return 0; +} +``` + +### 2. dynamic_cast operator + +`dynamic_cast` is a type-casting operator that performs a runtime type check and safely downcasts a base pointer or reference to a derived pointer or reference. It returns null or throws a bad_cast exception (if casting references) when the casting fails. + +Here is an example: +```cpp +#include + +class Base { virtual void dummy() {} }; +class Derived1 : public Base { /* ... */ }; +class Derived2 : public Base { /* ... */ }; + +int main() { + Base* base_ptr = new Derived1; + + // Using dynamic_cast to safely downcast the pointer + Derived1* derived1_ptr = dynamic_cast(base_ptr); + if (derived1_ptr) { + std::cout << "Downcast to Derived1 successful\n"; + } + else { + std::cout << "Downcast to Derived1 failed\n"; + } + + Derived2* derived2_ptr = dynamic_cast(base_ptr); + if (derived2_ptr) { + std::cout << "Downcast to Derived2 successful\n"; + } + else { + std::cout << "Downcast to Derived2 failed\n"; + } + + delete base_ptr; + return 0; +} +``` + +Please note that the use of RTTI can have some performance overhead, as it requires additional compiler-generated information to be stored and processed during runtime. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/104-data-types/101-dynamic-typing/index.md b/src/data/roadmaps/cpp/content/104-data-types/101-dynamic-typing/index.md index e2cf08d91..6c294acef 100644 --- a/src/data/roadmaps/cpp/content/104-data-types/101-dynamic-typing/index.md +++ b/src/data/roadmaps/cpp/content/104-data-types/101-dynamic-typing/index.md @@ -1 +1,60 @@ -# Dynamic typing \ No newline at end of file +# Dynamic Typing in C++ + +C++ is known as a statically-typed language, which means the data types of its variables are determined at compile time. However, C++ also provides concepts to have certain level of _dynamic typing_, which means determining the data types of variables at runtime. + +Here is a brief overview of two ways to achieve dynamic typing in C++: + +### 1. `void*` Pointers + +A `void*` pointer is a generic pointer that can point to objects of any data type. They can be used to store a reference to any type of object without knowing the specific type of the object. + +Example: +```cpp +#include + +int main() { + int x = 42; + float y = 3.14f; + std::string z = "Hello, world!"; + + void* void_ptr; + + void_ptr = &x; + std::cout << "int value: " << *(static_cast(void_ptr)) << std::endl; + + void_ptr = &y; + std::cout << "float value: " << *(static_cast(void_ptr)) << std::endl; + + void_ptr = &z; + std::cout << "string value: " << *(static_cast(void_ptr)) << std::endl; + + return 0; +} +``` + +### 2. `std::any` (C++17) + +C++17 introduced the `std::any` class which represents a generalized type-safe container for single values of any type. + +Example: +```cpp +#include +#include + +int main() { + std::any any_value; + + any_value = 42; + std::cout << "int value: " << std::any_cast(any_value) << std::endl; + + any_value = 3.14; + std::cout << "double value: " << std::any_cast(any_value) << std::endl; + + any_value = std::string("Hello, world!"); + std::cout << "string value: " << std::any_cast(any_value) << std::endl; + + return 0; +} +``` + +Keep in mind that both `void*` pointers and `std::any` have performance implications due to the additional type checking and casting that take place during runtime. They should be used carefully and only when absolutely necessary. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/105-pointers-and-references/100-references.md b/src/data/roadmaps/cpp/content/105-pointers-and-references/100-references.md index 949fccacf..917ef0dc2 100644 --- a/src/data/roadmaps/cpp/content/105-pointers-and-references/100-references.md +++ b/src/data/roadmaps/cpp/content/105-pointers-and-references/100-references.md @@ -1 +1,39 @@ -# References \ No newline at end of file +# References +A reference can be considered as a constant pointer (not to be confused with a pointer to a constant value) which always points to (references) the same object. They are declared using the `&` (ampersand) symbol. + +### Declaration and Initialization +To declare a reference, use the `&` symbol followed by the variable type and the reference's name. Note that you must initialize a reference when you declare it. + +```cpp +int var = 10; // Declare an integer variable +int& ref = var; // Declare a reference that "points to" var +``` + +### Usage +You can use the reference just like you'd use the original variable. When you change the value of the reference, the value of the original variable also changes, because they both share the same memory location. + +```cpp +var = 20; // Sets the value of var to 20 +cout << ref << endl; // Outputs 20 + +ref = 30; // Sets the value of ref to 30 +cout << var << endl; // Outputs 30 +``` + +### Function Parameters +You can use references as function parameters to create an alias for an argument. This is commonly done when you need to modify the original variable or when passing an object of considerable size to avoid the cost of copying. +```cpp +void swap(int& a, int& b) { + int temp = a; + a = b; + b = temp; +} + +int main() { + int x = 5, y = 10; + cout << "Before Swap: x = " << x << " y = " << y << endl; // Outputs 5 10 + + swap(x, y); + cout << "After Swap: x = " << x << " y = " << y << endl; // Outputs 10 5 +} +``` \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/105-pointers-and-references/101-memory-model/100-object-lifetime.md b/src/data/roadmaps/cpp/content/105-pointers-and-references/101-memory-model/100-object-lifetime.md index ca8681441..9e1f357c0 100644 --- a/src/data/roadmaps/cpp/content/105-pointers-and-references/101-memory-model/100-object-lifetime.md +++ b/src/data/roadmaps/cpp/content/105-pointers-and-references/101-memory-model/100-object-lifetime.md @@ -1 +1,40 @@ -# Object lifetime \ No newline at end of file +# Object Lifetime in C++ + +Object lifetime refers to the time during which an object exists, from the moment it is created until it is destroyed. In C++, an object's lifetime can be classified into four categories: + +1. **Static Storage Duration**: Objects with static storage duration exist for the entire run of the program. These objects are allocated at the beginning of the program's run and deallocated when the program terminates. Global variables, static data members, and static local variables fall into this category. + + ```cpp + int global_var; // Static storage duration + class MyClass { + static int static_var; // Static storage duration + }; + void myFunction() { + static int local_var; // Static storage duration + } + ``` + +2. **Thread Storage Duration**: Objects with thread storage duration exist for the lifetime of the thread they belong to. They are created when a thread starts and destroyed when the thread exits. Thread storage duration can be specified using the `thread_local` keyword. + + ```cpp + thread_local int my_var; // Thread storage duration + ``` + +3. **Automatic Storage Duration**: Objects with automatic storage duration are created at the point of definition and destroyed when the scope in which they are declared is exited. These objects are also known as "local" or "stack" objects. Function parameters and local non-static variables fall into this category. + + ```cpp + void myFunction() { + int local_var; // Automatic storage duration + } + ``` + +4. **Dynamic Storage Duration**: Objects with dynamic storage duration are created at runtime, using memory allocation functions such as `new` or `malloc`. The lifetime of these objects must be managed manually, as they are not automatically deallocated when the scope is exited. Instead, it is the programmer's responsibility to destroy the objects using the `delete` or `free` functions when they are no longer needed, to avoid memory leaks. + + ```cpp + int* ptr = new int; // Dynamic storage duration + delete ptr; + ``` + +Understanding object lifetimes is essential for managing memory efficiently in C++ programs and avoiding common issues like memory leaks and undefined behavior. + +Keep in mind that a proper understanding of constructors and destructors for classes is also essential when working with objects of varying lifetimes, as they allow you to control the behavior of object creation and destruction. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/105-pointers-and-references/index.md b/src/data/roadmaps/cpp/content/105-pointers-and-references/index.md index fcbd26813..b5ac5bf6f 100644 --- a/src/data/roadmaps/cpp/content/105-pointers-and-references/index.md +++ b/src/data/roadmaps/cpp/content/105-pointers-and-references/index.md @@ -1 +1,41 @@ -# Pointers and references \ No newline at end of file +# Pointers + +A pointer is a variable that stores the memory address of another variable (or function). It points to the location of the variable in memory, and it allows you to access or modify the value indirectly. Here's a general format to declare a pointer: + +```cpp +dataType *pointerName; +``` + +**Initializing a pointer:** + +```cpp +int num = 10; +int *ptr = # // Pointer 'ptr' now points to the memory address of 'num' +``` + +**Accessing value using a pointer:** + +```cpp +int value = *ptr; // Value now contains the value of the variable that 'ptr' points to (i.e., 10) +``` + +## References + +A reference is an alias for an existing variable, meaning it's a different name for the same memory location. Unlike pointers, references cannot be null, and they must be initialized when they are declared. Once a reference is initialized, it cannot be changed to refer to another variable. + +Here's a general format to declare a reference: + +```cpp +dataType &referenceName = existingVariable; +``` + +**Example:** + +```cpp +int num = 10; +int &ref = num; // Reference 'ref' is now an alias of 'num' +``` + +Modifying the value of `ref` will also modify the value of `num` because they share the same memory location. + +**Note:** References are generally used when you want to pass a variable by reference in function arguments or when you want to create an alias for a variable without the need for pointer syntax. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/105-pointers-and-references/raw-pointers/100-new-delete-operators.md b/src/data/roadmaps/cpp/content/105-pointers-and-references/raw-pointers/100-new-delete-operators.md index 702caf731..6ebe73adc 100644 --- a/src/data/roadmaps/cpp/content/105-pointers-and-references/raw-pointers/100-new-delete-operators.md +++ b/src/data/roadmaps/cpp/content/105-pointers-and-references/raw-pointers/100-new-delete-operators.md @@ -1 +1,47 @@ -# New delete operators \ No newline at end of file +# Raw Pointers and `new` and `delete` operators + +Raw pointers in C++ are low-level constructs that directly hold a memory address. They can be used for manually allocating memory, creating dynamic arrays, and passing values efficiently, among other things. + +### `new` Operator + +The `new` operator is used to allocate memory on the heap. The memory allocated using `new` remains available until you explicitly deallocate it using the corresponding `delete` operator. + +Here's an example of using the `new` operator: + +```cpp +int* ptr = new int; // Dynamically allocates an int on the heap +*ptr = 42; // Assigns the value 42 to the allocated int +``` + +### `delete` Operator + +The `delete` operator is used to deallocate memory that has been allocated using `new`. After memory is deallocated, it's available to be reallocated for other purposes. Failing to properly deallocate memory can lead to memory leaks. + +Here's an example of using the `delete` operator: + +```cpp +int* ptr = new int; // Dynamically allocates an int on the heap +*ptr = 42; // Assigns the value 42 to the allocated int + +delete ptr; // Deallocates the memory assigned to ptr +``` + +### `new[]` and `delete[]` Operators + +The `new[]` and `delete[]` operators are used for allocating and deallocating memory for an array of objects. The syntax for `new[]` and `delete[]` is very similar to that of `new` and `delete`. + +Here's an example of using the `new[]` and `delete[]` operators: + +```cpp +int n = 10; +int* arr = new int[n]; // Dynamically allocates an array of 10 integers on the heap + +// Set some values in the array +for (int i = 0; i < n; i++) { + arr[i] = i; +} + +delete[] arr; // Deallocates the memory assigned to the array +``` + +In summary, raw pointers, and `new` and `delete` operators allow manual memory management in C++, providing control over allocation and deallocation. Make sure to always deallocate memory allocated with `new` or `new[]`, to avoid memory leaks in your programs. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/105-pointers-and-references/raw-pointers/101-memory-leakage.md b/src/data/roadmaps/cpp/content/105-pointers-and-references/raw-pointers/101-memory-leakage.md index adc28f90e..5fb1d274e 100644 --- a/src/data/roadmaps/cpp/content/105-pointers-and-references/raw-pointers/101-memory-leakage.md +++ b/src/data/roadmaps/cpp/content/105-pointers-and-references/raw-pointers/101-memory-leakage.md @@ -1 +1,28 @@ -# Memory leakage \ No newline at end of file +# Memory Leakage + +Memory leakage occurs when a program allocates memory in the heap but does not release the memory back to the operating system when it is no longer needed. Over time, this leads to exhaustion of available memory, resulting in low system performance or crashes. + +In C++, when you use raw pointers, you need to manage the memory allocation and deallocation manually. In many cases, you will use the `new` keyword to allocate memory for an object in the heap and use `delete` keyword to deallocate that memory when it's no longer needed. Forgetting to do this can cause memory leaks. + +Here's an example: + +```cpp +void create_memory_leak() { + int* ptr = new int[100]; // Allocating memory in the heap for an array of integers + // Some code... + // Code to deallocate the memory is missing: delete[] ptr; +} // ptr goes out of scope, memory block allocated is not deallocated, causing a memory leak. +``` + +To avoid memory leaks, you should always ensure that memory is deallocated before a pointer goes out of scope or is reassigned. Some ways to achieve this include using the C++ smart pointers (`std::unique_ptr`, `std::shared_ptr`), RAII (Resource Acquisition Is Initialization) techniques, and containers from the C++ standard library that manage memory allocation internally (e.g., `std::vector`, `std::string`). + +For example, this code will not have a memory leak: + +```cpp +#include + +void no_memory_leak() { + std::shared_ptr ptr = std::make_shared(100); // Allocating memory in the heap for an array of integers using shared_ptr + // Some code... +} // shared_ptr goes out of scope and it will automatically deallocate the memory block assigned to it. +``` \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/100-weak-ptr.md b/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/100-weak-ptr.md index 3ec76e331..040448358 100644 --- a/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/100-weak-ptr.md +++ b/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/100-weak-ptr.md @@ -1 +1,48 @@ -# Weak ptr \ No newline at end of file +# Weak Pointer + +A `weak_ptr` is a type of smart pointer in C++ that adds a level of indirection and safety to a raw pointer. It is mainly used to break reference cycles in cases where two objects have shared pointers to each other, or when you need a non-owning reference to an object that is managed by a `shared_ptr`. + +A `weak_ptr` doesn't increase the reference count of the object it points to, which is a crucial distinction between `weak_ptr` and `shared_ptr`. This ensures that the object will be deleted once the last `shared_ptr` that owns it goes out of scope, even if there are `weak_ptr`s still referencing it. + +To use a `weak_ptr`, you must convert it to a `shared_ptr` using the `lock()` function, which tries to create a new `shared_ptr` that shares ownership of the object. If successful, the object's reference count is increased and you can use the returned `shared_ptr` to safely access the object. + +Here's an example of using `weak_ptr`: + +```cpp +#include +#include + +class MyClass { +public: + void DoSomething() { + std::cout << "Doing something...\n"; + } +}; + +int main() { + std::weak_ptr weak; + + { + std::shared_ptr shared = std::make_shared(); + weak = shared; + + if(auto sharedFromWeak = weak.lock()) { + sharedFromWeak->DoSomething(); // Safely use the object + std::cout << "Shared uses count: " << sharedFromWeak.use_count() << '\n'; // 2 + } + } + + // shared goes out of scope and the MyClass object is destroyed + + if(auto sharedFromWeak = weak.lock()) { + // This block will not be executed because the object is destroyed + } + else { + std::cout << "Object has been destroyed\n"; + } + + return 0; +} +``` + +In this example, we create a `shared_ptr` named `shared` that manages a `MyClass` object. By assigning it to a `weak_ptr` named `weak`, we store a non-owning reference to the object. Inside the inner scope, we create a new `shared_ptr` named `sharedFromWeak` using `weak.lock()` to safely use the object. After the inner scope, the `MyClass` object is destroyed since `shared` goes out of scope, and any further attempt to create a `shared_ptr` from `weak` will fail as the object is already destroyed. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/101-shared-ptr.md b/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/101-shared-ptr.md index d72118f23..65c6fdd5b 100644 --- a/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/101-shared-ptr.md +++ b/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/101-shared-ptr.md @@ -1 +1,50 @@ -# Shared ptr \ No newline at end of file +# Shared Pointer + +A `shared_ptr` is a type of smart pointer in C++ that allows multiple pointers to share ownership of a dynamically allocated object. The object will be automatically deallocated only when the last `shared_ptr` that points to it is destroyed. + +When using a `shared_ptr`, the reference counter is automatically incremented every time a new pointer is created, and decremented when each pointer goes out of scope. Once the reference counter reaches zero, the system will clean up the memory. + +### Code Example + +Here's an example of how to use `shared_ptr`: + +```cpp +#include +#include + +class MyClass { +public: + MyClass() { std::cout << "Constructor is called." << std::endl; } + ~MyClass() { std::cout << "Destructor is called." << std::endl; } +}; + +int main() { + // create a shared pointer to manage the MyClass object + std::shared_ptr ptr1(new MyClass()); + + { + // create another shared pointer and initialize it with the previously created pointer + std::shared_ptr ptr2 = ptr1; + + std::cout << "Inside the inner scope." << std::endl; + // both pointers share the same object, and the reference counter has been increased to 2 + } + + std::cout << "Outside the inner scope." << std::endl; + // leaving the inner scope will destroy ptr2, and the reference counter is decremented to 1 + + // the main function returns, ptr1 goes out of scope, and the reference counter becomes 0 + // this causes the MyClass object to be deleted and the destructor is called +} +``` + +Output: + +``` +Constructor is called. +Inside the inner scope. +Outside the inner scope. +Destructor is called. +``` + +In this example, `ptr1` and `ptr2` share ownership of the same object. The object is only destroyed when both pointers go out of scope and the reference counter becomes zero. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/102-uniqe-ptr.md b/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/102-uniqe-ptr.md index 6fd1cb3a4..709f19c26 100644 --- a/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/102-uniqe-ptr.md +++ b/src/data/roadmaps/cpp/content/105-pointers-and-references/smart-pointers/102-uniqe-ptr.md @@ -1 +1,66 @@ -# Uniqe ptr \ No newline at end of file +# Unique Pointer (`unique_ptr`) + +`std::unique_ptr` is a smart pointer provided by the C++ Standard Library. It is a template class that is used for managing single objects or arrays. + +`unique_ptr` works on the concept of *exclusive ownership* - meaning only one `unique_ptr` is allowed to own an object at a time. This ownership can be transferred or moved, but it cannot be shared or copied. + +This concept helps to prevent issues like dangling pointers, reduce memory leaks, and eliminates the need for manual memory management. When the `unique_ptr` goes out of scope, it automatically deletes the object it owns. + +Let's take a look at some basic examples of using `unique_ptr`: + +## Creating a unique_ptr + +```cpp +#include +#include + +int main() { + std::unique_ptr p1(new int(5)); // Initialize with pointer to a new integer + std::unique_ptr p2 = std::make_unique(10); // Preferred method (C++14 onwards) + + std::cout << *p1 << ", " << *p2 << std::endl; + return 0; +} +``` + +## Transferring Ownership + +```cpp +#include +#include + +int main() { + std::unique_ptr p1(new int(5)); + + std::unique_ptr p2 = std::move(p1); // Ownership is transferred from p1 to p2 + + if (p1) { + std::cout << "p1 owns the object" << std::endl; + } else if (p2) { + std::cout << "p2 owns the object" << std::endl; + } + + return 0; +} +``` + +## Using unique_ptr with Custom Deleters + +```cpp +#include +#include + +struct MyDeleter { + void operator()(int* ptr) { + std::cout << "Custom Deleter: Deleting pointer" << std::endl; + delete ptr; + } +}; + +int main() { + std::unique_ptr p1(new int(5), MyDeleter()); + return 0; // Custom Deleter will be called when p1 goes out of scope +} +``` + +Remember that since unique_ptr has exclusive ownership, you cannot use it when you need shared access to an object. For such cases, you can use `std::shared_ptr`. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/106-structuring-codebase/100-scope/index.md b/src/data/roadmaps/cpp/content/106-structuring-codebase/100-scope/index.md index be880e0de..ad5409b0b 100644 --- a/src/data/roadmaps/cpp/content/106-structuring-codebase/100-scope/index.md +++ b/src/data/roadmaps/cpp/content/106-structuring-codebase/100-scope/index.md @@ -1 +1,70 @@ -# Scope \ No newline at end of file +# Scope in C++ + +**Scope** refers to the visibility and accessibility of variables, functions, classes, and other identifiers in a C++ program. It determines the lifetime and extent of these identifiers. In C++, there are four types of scope: + +1. **Global scope:** Identifiers declared outside any function or class have a global scope. They can be accessed from any part of the program (unless hidden by a local identifier with the same name). The lifetime of a global identifier is the entire duration of the program. + +```cpp +#include + +int globalVar; // This is a global variable + +int main() { + std::cout << "Global variable: " << globalVar << std::endl; +} +``` + +2. **Local scope:** Identifiers declared within a function or a block have a local scope. They can be accessed only within the function or the block they were declared in. Their lifetime is limited to the duration of the function/block execution. + +```cpp +#include + +void localExample() { + int localVar; // This is a local variable + localVar = 5; + std::cout << "Local variable: " << localVar << std::endl; +} + +int main() { + localExample(); + // std::cout << localVar << std::endl; //error: ‘localVar’ was not declared in this scope +} +``` + +3. **Namespace scope:** A namespace is a named scope that groups related identifiers together. Identifiers declared within a namespace have the namespace scope. They can be accessed using the namespace name and the scope resolution operator `::`. + +```cpp +#include + +namespace MyNamespace { + int namespaceVar = 42; +} + +int main() { + std::cout << "Namespace variable: " << MyNamespace::namespaceVar << std::endl; +} +``` + +4. **Class scope:** Identifiers declared within a class have a class scope. They can be accessed using the class name and the scope resolution operator `::` or, for non-static members, an object of the class and the dot `.` or arrow `->` operator. + +```cpp +#include + +class MyClass { +public: + static int staticMember; + int nonStaticMember; + + MyClass(int value) : nonStaticMember(value) {} +}; + +int MyClass::staticMember = 7; + +int main() { + MyClass obj(10); + std::cout << "Static member: " << MyClass::staticMember << std::endl; + std::cout << "Non-static member: " << obj.nonStaticMember << std::endl; +} +``` + +Understanding various types of scope in C++ is essential for effective code structuring and management of resources in a codebase. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/106-structuring-codebase/101-code-splitting/100-forward-declaration.md b/src/data/roadmaps/cpp/content/106-structuring-codebase/101-code-splitting/100-forward-declaration.md index c03bca246..51f3a4b99 100644 --- a/src/data/roadmaps/cpp/content/106-structuring-codebase/101-code-splitting/100-forward-declaration.md +++ b/src/data/roadmaps/cpp/content/106-structuring-codebase/101-code-splitting/100-forward-declaration.md @@ -1 +1,47 @@ -# Forward declaration \ No newline at end of file +# Forward Declaration + +Forward declaration is a way of declaring a symbol (class, function, or variable) before defining it in the code. It helps the compiler understand the type, size, and existence of the symbol. This declaration is particularly useful when we have cyclic dependencies or to reduce compilation time by avoiding unnecessary header inclusions in the source file. + +### Class Forward Declaration + +To use a class type before it is defined, you can declare the class without defining its members, like this: + +```cpp +class ClassA; // forward declaration +``` + +You can then use pointers or references to the class in your code before defining the class itself: + +```cpp +void do_something (ClassA& obj); + +class ClassB { +public: + void another_function(ClassA& obj); +}; +``` + +However, if you try to make an object of `ClassA` or call its member functions without defining the class, you will get a compilation error. + +### Function Forward Declaration + +Functions must be declared before using them, and a forward declaration can be used to declare a function without defining it: + +```cpp +int add(int a, int b); // forward declaration + +int main() { + int result = add(2, 3); + return 0; +} + +int add(int a, int b) { + return a + b; +} +``` + +### Enum and Typedef Forward Declaration + +For `enum` and `typedef`, it is not possible to forward declare because they don't have separate declaration and definition stages. + +Keep in mind that forward declarations should be used cautiously, as they can make the code more difficult to understand. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/100-static-polymorphism/index.md b/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/100-static-polymorphism/index.md index 184c30191..7551961e4 100644 --- a/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/100-static-polymorphism/index.md +++ b/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/100-static-polymorphism/index.md @@ -1 +1,59 @@ -# Static polymorphism \ No newline at end of file +# Static Polymorphism + +Static polymorphism, also known as compile-time polymorphism, is a type of polymorphism that resolves the types and method calls at compile time rather than at runtime. This is commonly achieved through the use of function overloading and templates in C++. + +### Function Overloading + +Function overloading is a way to create multiple functions with the same name but different parameter lists. The compiler determines the correct function to call based on the types and number of arguments used when the function is called. + +Example: + +```cpp +#include + +void print(int i) { + std::cout << "Printing int: " << i << std::endl; +} + +void print(double d) { + std::cout << "Printing double: " << d << std::endl; +} + +void print(const char* s) { + std::cout << "Printing string: " << s << std::endl; +} + +int main() { + print(5); // Calls print(int i) + print(3.14); // Calls print(double d) + print("Hello"); // Calls print(const char* s) + + return 0; +} +``` + +### Templates + +Templates are a powerful feature in C++ that allows you to create generic functions or classes. The actual code for specific types is generated at compile time, which avoids the overhead of runtime polymorphism. The use of templates is the main technique to achieve static polymorphism in C++. + +Example: + +```cpp +#include + +// Template function to print any type +template +void print(const T& value) { + std::cout << "Printing value: " << value << std::endl; +} + +int main() { + print(42); // int + print(3.14159); // double + print("Hello"); // const char* + + return 0; +} +``` + +In conclusion, static polymorphism achieves polymorphic behavior during compile time using function overloading and templates, instead of relying on runtime information like dynamic polymorphism does. This can result in more efficient code since method calls are resolved at compile time. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/100-static-polymorphism/overloading-functions.md b/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/100-static-polymorphism/overloading-functions.md index 38c985fa8..9c60bfff7 100644 --- a/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/100-static-polymorphism/overloading-functions.md +++ b/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/100-static-polymorphism/overloading-functions.md @@ -1 +1,46 @@ -# Overloading functions \ No newline at end of file +# Function Overloading + +Function overloading is a type of static polymorphism in C++ where multiple functions with the same name but different sets of parameters are defined in the same scope. This allows you to use the same function name for multiple tasks by providing different arguments while calling the function. The appropriate function to call is determined during compile-time based on the number and types of the arguments passed. + +To overload a function, simply define another function with the same name but a different set of parameters. The compiler will automatically choose the correct function to call based on the provided arguments. + +### Examples + +Here's an example illustrating function overloading: + +```cpp +#include +using namespace std; + +void print(int num) { + cout << "Printing int: " << num << endl; +} + +void print(double num) { + cout << "Printing double: " << num << endl; +} + +void print(char const *str) { + cout << "Printing string: " << str << endl; +} + +int main() { + print(5); + print(3.14); + print("Hello, world!"); + + return 0; +} +``` + +In this example, three overloaded functions named `print` are defined. They each take a different type of argument: `int`, `double`, and `char const *`. When calling `print()` with different arguments like `5`, `3.14`, or `"Hello, world!"`, the appropriate function is chosen based on the type of the provided argument. + +The output of this program would be: + +``` +Printing int: 5 +Printing double: 3.14 +Printing string: Hello, world! +``` + +Keep in mind that the number of parameters and their types should be different for two functions to be overloaded. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/index.md b/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/index.md index 2d14db528..98eed9ce6 100644 --- a/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/index.md +++ b/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/index.md @@ -1 +1,66 @@ -# Dynamic polymorphism \ No newline at end of file +# Dynamic Polymorphism + +Dynamic polymorphism is a programming concept in object-oriented languages like C++ where a derived class can override or redefine methods of its base class. This means that a single method call can have different implementations based on the type of object it is called on. + +Dynamic polymorphism is achieved through **virtual functions**, which are member functions of a base class marked with the `virtual` keyword. When you specify a virtual function in a base class, it can be overridden in any derived class to provide a different implementation. + +### Example + +Here's an example in C++ demonstrating dynamic polymorphism. + +```cpp +#include + +// Base class +class Shape { +public: + virtual void draw() { + std::cout << "Drawing a shape" << std::endl; + } +}; + +// Derived class 1 +class Circle : public Shape { +public: + void draw() override { + std::cout << "Drawing a circle" << std::endl; + } +}; + +// Derived class 2 +class Rectangle : public Shape { +public: + void draw() override { + std::cout << "Drawing a rectangle" << std::endl; + } +}; + +int main() { + Shape* shape; + Circle circle; + Rectangle rectangle; + + // Storing the address of circle + shape = &circle; + + // Call circle draw function + shape->draw(); + + // Storing the address of rectangle + shape = &rectangle; + + // Call rectangle draw function + shape->draw(); + + return 0; +} +``` + +This code defines a base class `Shape` with a virtual function `draw`. Two derived classes `Circle` and `Rectangle` both override the `draw` function to provide their own implementations. Then in the `main` function, a pointer of type `Shape` is used to call the respective `draw` functions of `Circle` and `Rectangle` objects. The output of this program will be: + +``` +Drawing a circle +Drawing a rectangle +``` + +As you can see, using dynamic polymorphism, we can determine at runtime which `draw` method should be called based on the type of object being used. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/virtual-methods.md b/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/virtual-methods.md index 7c9c2c6ef..a8a17b282 100644 --- a/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/virtual-methods.md +++ b/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/virtual-methods.md @@ -1 +1,65 @@ -# Virtual methods \ No newline at end of file +# Virtual Methods + +Virtual methods are a key aspect of dynamic polymorphism in C++. They allow subclass methods to override the methods of their base class, so the appropriate method is called depending on the actual type of an object at runtime. + +To declare a method as virtual, simply use the `virtual` keyword in the method's declaration in the base class. This tells the compiler that the method should be treated as a virtual method, allowing it to be overridden by derived classes. + +### Code Example + +Here's an example demonstrating virtual methods: + +```cpp +#include + +// Base class +class Shape { +public: + virtual double area() const { + return 0; + } +}; + +// Derived class +class Circle : public Shape { +public: + Circle(double r) : radius(r) {} + + // Override the base class method + double area() const override { + return 3.14 * radius * radius; + } + +private: + double radius; +}; + +// Derived class +class Rectangle : public Shape { +public: + Rectangle(double w, double h) : width(w), height(h) {} + + // Override the base class method + double area() const override { + return width * height; + } + +private: + double width; + double height; +}; + +int main() { + Circle c(5); + Rectangle r(4, 6); + + Shape* shape = &c; + std::cout << "Circle's area: " << shape->area() << std::endl; + + shape = &r; + std::cout << "Rectangle's area: " << shape->area() << std::endl; + + return 0; +} +``` + +In this example, we define a base class `Shape` that has a virtual method `area`. This method is then overridden by the derived classes `Circle` and `Rectangle`. By using a virtual method and a base class pointer to the derived objects, we can invoke the appropriate `area` method based on the actual object type at runtime. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/virtual-tables.md b/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/virtual-tables.md index 273d22f3d..15783bad7 100644 --- a/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/virtual-tables.md +++ b/src/data/roadmaps/cpp/content/107-structures-and-classes/101-oop/101-dynamic-polymorphism/virtual-tables.md @@ -1 +1,51 @@ -# Virtual tables \ No newline at end of file +# Virtual Tables + +Virtual Tables (or Vtable) are a mechanism used by C++ compilers to support dynamic polymorphism. In dynamic polymorphism, the appropriate function is called at runtime, depending on the actual object type. + +When a class contains a virtual function, the compiler creates a virtual table for that class. This table contains function pointers to the virtual functions defined in the class. Each object of that class has a pointer to its virtual table (_vptr_, virtual pointer), which is automatically initialized by the compiler during object construction. + +### Example + +Let's consider the following example: + +```cpp +class Base { +public: + virtual void function1() { + std::cout << "Base::function1" << std::endl; + } + + virtual void function2() { + std::cout << "Base::function2" << std::endl; + } +}; + +class Derived : public Base { +public: + void function1() override { + std::cout << "Derived::function1" << std::endl; + } + + void function3() { + std::cout << "Derived::function3" << std::endl; + } +}; + +int main() { + Base* obj = new Derived(); // create a Derived object and assign a pointer of type Base* + obj->function1(); // calls Derived::function1, due to dynamic polymorphism + obj->function2(); // calls Base::function2 + + delete obj; + return 0; +} +``` + +In this example, when a `Derived` object is created, the compiler generates a Vtable for `Derived` class, containing pointers to its virtual functions: + +- `Derived::function1` (overridden from `Base`) +- `Base::function2` (inherits from Base) + +The `_vptr_` pointer in the `Derived` object points to this Vtable. When the `function1` is called on the `Base` pointer pointing to the `Derived` object, the function pointer in the Vtable is used to call the correct function (in this case, `Derived::function1`). Similarly, the call to `function2` calls `Base::function2`, since it's the function pointer stored in the Vtable for `Derived` class. + +Note that `function3` is not part of the Vtable, as it is not a virtual function. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/107-structures-and-classes/102-multiple-inheritance/100-diamond-inheritance.md b/src/data/roadmaps/cpp/content/107-structures-and-classes/102-multiple-inheritance/100-diamond-inheritance.md index e9b2ab825..cd88336dc 100644 --- a/src/data/roadmaps/cpp/content/107-structures-and-classes/102-multiple-inheritance/100-diamond-inheritance.md +++ b/src/data/roadmaps/cpp/content/107-structures-and-classes/102-multiple-inheritance/100-diamond-inheritance.md @@ -1 +1,53 @@ -# Diamond inheritance \ No newline at end of file +# Diamond Inheritance + +Diamond inheritance is a specific scenario in multiple inheritance where a class is derived from two or more classes, which in turn, are derived from a common base class. It creates an ambiguity that arises from duplicating the common base class, which leads to an ambiguous behavior while calling the duplicate members. + +To resolve this ambiguity, you can use virtual inheritance. A virtual base class is a class that is shared by multiple classes using `virtual` keyword in C++. This ensures that only one copy of the base class is inherited in the final derived class, and thus, resolves the diamond inheritance problem. + +*Example:* + +```cpp +#include +using namespace std; + +class Base { +public: + void print() { + cout << "Base class" << endl; + } +}; + +class Derived1 : virtual public Base { +public: + void derived1Print() { + cout << "Derived1 class" << endl; + } +}; + +class Derived2 : virtual public Base { +public: + void derived2Print() { + cout << "Derived2 class" << endl; + } +}; + +class Derived3 : public Derived1, public Derived2 { +public: + void derived3Print() { + cout << "Derived3 class" << endl; + } +}; + +int main() +{ + Derived3 d3; + d3.print(); // Now, there is no ambiguity in calling the base class function + d3.derived1Print(); + d3.derived2Print(); + d3.derived3Print(); + + return 0; +} +``` + +In the code above, `Derived1` and `Derived2` are derived from the `Base` class using virtual inheritance. So, when we create an object of `Derived3` and call the `print()` function from the `Base` class, there is no ambiguity, and the code executes without any issues. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/107-structures-and-classes/index.md b/src/data/roadmaps/cpp/content/107-structures-and-classes/index.md index 39b0ca557..c7a34ab06 100644 --- a/src/data/roadmaps/cpp/content/107-structures-and-classes/index.md +++ b/src/data/roadmaps/cpp/content/107-structures-and-classes/index.md @@ -1 +1,65 @@ -# Structures and classes \ No newline at end of file +# Structures and Classes in C++ + +Structures and classes are user-defined data types in C++ that allow for the grouping of variables of different data types under a single name. They make it easier to manage and organize complex data by creating objects that have particular attributes and behaviors. The main difference between a structure and a class is their default access specifier: members of a structure are public by default, while members of a class are private. + +## Structures + +A structure is defined using the `struct` keyword, followed by the structure's name and a set of curly braces `{}` enclosing the members (variables and/or functions) of the structure. The members can be of different data types. To create an object of the structure's type, use the structure name followed by the object name. + +Here's an example of defining a structure and creating an object: + +```cpp +struct Employee { + int id; + std::string name; + float salary; +}; + +Employee e1; // create an object of the 'Employee' structure +``` + +You can access the members of a structure using the dot operator `.`: + +```cpp +e1.id = 1; +e1.name = "John Doe"; +e1.salary = 40000; +``` + +## Classes + +A class is defined using the `class` keyword, followed by the class's name and a set of curly braces `{}` enclosing the members (variables and/or functions) of the class. Like structures, class members can be of different data types. You can create objects of a class using the class name followed by the object name. + +Here's an example of a class definition and object creation: + +```cpp +class Student { + int roll_no; + std::string name; + float marks; + +public: + void set_data(int r, std::string n, float m) { + roll_no = r; + name = n; + marks = m; + } + + void display() { + std::cout << "Roll no: " << roll_no + << "\nName: " << name + << "\nMarks: " << marks << std::endl; + } +}; + +Student s1; // create an object of the 'Student' class +``` + +Since the data members of a class are private by default, we cannot access them directly using the dot operator from outside the class. Instead, we use public member functions to set or get their values: + +```cpp +s1.set_data(1, "Alice", 95.0); +s1.display(); +``` + +That's a brief summary of structures and classes in C++. Remember that while they may seem similar, classes provide more control over data encapsulation and can be used to implement more advanced features like inheritance and polymorphism. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/108-exception-handling/100-exceptions/index.md b/src/data/roadmaps/cpp/content/108-exception-handling/100-exceptions/index.md index 9617c0da2..a9c02e8e8 100644 --- a/src/data/roadmaps/cpp/content/108-exception-handling/100-exceptions/index.md +++ b/src/data/roadmaps/cpp/content/108-exception-handling/100-exceptions/index.md @@ -1 +1,50 @@ -# Exceptions \ No newline at end of file +# Exception Handling in C++ + +Exception handling is a method used to tackle runtime errors so that normal flow of the program can be maintained. In C++, this is accomplished using three keywords: `try`, `catch`, and `throw`. + +## try { ... } +In the `try` block, you write the code that can possibly generate an exception. If an exception is encountered, the control is passed to the relevant `catch` block to handle the issue. + +Example: +```cpp +try { + // code that might throw an exception +} +``` + +## catch (...) { ... } +The `catch` block follows the `try` block and is responsible for handling the exceptions thrown by the `try` block. There can be multiple `catch` blocks to handle different types of exceptions. + +Example: +```cpp +catch (int e) { + // handle exception of type int +} +catch (char e) { + // handle exception of type char +} +catch (...) { + // handle any other exception +} +``` + +## throw ... ; +In case an error occurs within the `try` block, you can use the `throw` keyword to generate an exception of the specific type. This will then be caught and handled by the corresponding `catch` block. + +Example: +```cpp +try { + int num1 = 10, num2 = 0; + if (num2 == 0) { + throw "Division by zero not allowed!"; + } else { + int result = num1 / num2; + cout << "Result: " << result << endl; + } +} +catch (const char* e) { + cout << "Error: " << e << endl; +} +``` + +In summary, exception handling in C++ is a technique to handle runtime errors while maintaining the normal flow of the program. The `try`, `catch`, and `throw` keywords are used together to create the structure to deal with exceptions as they occur. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/108-exception-handling/101-exit-codes.md b/src/data/roadmaps/cpp/content/108-exception-handling/101-exit-codes.md index bb25fb41b..9488bf7a4 100644 --- a/src/data/roadmaps/cpp/content/108-exception-handling/101-exit-codes.md +++ b/src/data/roadmaps/cpp/content/108-exception-handling/101-exit-codes.md @@ -1 +1,59 @@ -# Exit codes \ No newline at end of file +# Exit Codes + +Exit codes, also known as "return codes" or "status codes", are numeric values that a program returns to the calling environment (usually the operating system) when it finishes execution. These codes are used to indicate the success or failure of a program's execution. + +0 is the standard exit code for a successful execution, while non-zero exit codes typically indicate errors or other exceptional situations. The actual meanings of non-zero exit codes can vary between different applications or systems. + +In C++, you can return an exit code from the `main` function by using the `return` statement, or you can use the `exit()` function, which is part of the C++ Standard Library. + +### Example: Using return in `main` + +```cpp +#include + +int main() { + // Some code here... + + if (/*some error condition*/) { + std::cout << "An error occurred." << std::endl; + return 1; + } + + // More code here... + + if (/*another error condition*/) { + std::cout << "Another error occurred." << std::endl; + return 2; + } + + return 0; // Successful execution +} +``` + +### Example: Using the `exit()` function + +```cpp +#include +#include + +void some_function() { + // Some code here... + + if (/*some error condition*/) { + std::cout << "An error occurred." << std::endl; + std::exit(1); + } + + // More code here... +} + +int main() { + some_function(); + + // Some other code here... + + return 0; // Successful execution +} +``` + +In both examples above, the program returns exit codes depending on different error conditions encountered during execution. The codes 1 and 2 are used to distinguish between the two error conditions. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/109-language-concepts/100-auto.md b/src/data/roadmaps/cpp/content/109-language-concepts/100-auto.md index 9b4da6d3f..6759a5f1f 100644 --- a/src/data/roadmaps/cpp/content/109-language-concepts/100-auto.md +++ b/src/data/roadmaps/cpp/content/109-language-concepts/100-auto.md @@ -1 +1,49 @@ -# Auto \ No newline at end of file +# auto (Automatic Type Deduction) + +**Auto** + +`auto` is a keyword in C++ language introduced in C++11, which is used for automatic type deduction. It automatically deduces the type of a variable from the type of its initializer expression at compile time. + +The `auto` keyword is useful when you are dealing with complex types or when the type of a variable is hard to predict. It can help in writing cleaner and less error-prone code. + +Here's a simple example of using `auto` for type deduction: + +```cpp +#include +#include + +int main() { + // Traditional way of declaring a variable: + int myInt = 5; + + // Using auto for type deduction: + auto myAutoInt = 5; // Automatically deduces the type as 'int' + + // Example with more complex types: + std::vector myVector = {1, 2, 3, 4, 5}; + + // Without auto, iterating the vector would look like this: + for (std::vector::iterator it = myVector.begin(); it != myVector.end(); ++it) { + std::cout << *it << std::endl; + } + + // With auto, the iterator declaration becomes simpler: + for (auto it = myVector.begin(); it != myVector.end(); ++it) { + std::cout << *it << std::endl; + } +} +``` + +Keep in mind that `auto` deduces the type based on the initializer expression, so if you don't provide an initial value, you will get a compile-time error: + +```cpp +auto myVar; // Error: Cannot deduce the type without initializer +``` + +In C++14, you can also use `auto` with function return types to let the compiler automatically deduce the return type based on the returned expression: + +```cpp +auto add(int x, int y) { + return x + y; // The compiler deduces the return type as 'int' +} +``` \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/100-static-cast.md b/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/100-static-cast.md index 56fbf02c0..748251046 100644 --- a/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/100-static-cast.md +++ b/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/100-static-cast.md @@ -1 +1,40 @@ -# Static cast \ No newline at end of file +# Static Cast + +`static_cast` is one of the casting operators in C++ that allows you to convert between different data types, such as integer and float, or between pointer types. This type of cast performs a compile-time check and gives an error if there is no valid conversion possible between given types. `static_cast` is generally safer than C-style casts since it does not perform an unsafe reinterpretation of data and allows for better type checking. + +### Syntax + +The syntax for `static_cast` is as follows: + +```cpp +static_cast(expression) +``` + +### Examples + +1. Converting between basic data types: + +```cpp +int i = 42; +float f = static_cast(i); // Converts integer i to float f +``` + +2. Casting pointers of different object types in an inheritance hierarchy: + +```cpp +class Base { /* ... */ }; +class Derived : public Base { /* ... */ }; + +Base *bPtr = new Derived; +Derived *dPtr = static_cast(bPtr); // Converts Base pointer bPtr to Derived pointer dPtr +``` + +3. Converting an integer to an enumeration: + +```cpp +enum Color { RED, GREEN, BLUE }; +int value = 1; +Color color = static_cast(value); // Converts integer value to corresponding Color enumeration +``` + +Keep in mind that `static_cast` should be used with caution when casting pointers between different object types. If the original type of the pointer does not match the target type, the result of the cast can be incorrect or cause unexpected behavior. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/101-const-cast.md b/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/101-const-cast.md index 48adabffa..719516875 100644 --- a/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/101-const-cast.md +++ b/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/101-const-cast.md @@ -1 +1,32 @@ -# Const cast \ No newline at end of file +# const_cast + +`const_cast` is a type of casting in C++ that allows you to remove or add constness to a variable. In other words, it enables you to modify a `const` or `volatile` object, or change a pointer or reference to a `const` or `volatile` type. This is useful in certain scenarios when you need to pass a `const` variable as an argument or when a function parameter requires a non-const type, but you want to make sure the variable remains constant throughout the code. + +Keep in mind that using `const_cast` to modify a truly `const` variable can lead to undefined behavior, so it is best to use this feature only when absolutely necessary. + +### Example + +Here's a code example showing how to use `const_cast`: + +```cpp +#include + +void modifyVariable(int* ptr) { + *ptr = 42; +} + +int main() { + const int original_value = 10; + int* non_const_value_ptr = const_cast(&original_value); + std::cout << "Original value: " << original_value << std::endl; + + modifyVariable(non_const_value_ptr); + std::cout << "Modified value: " << *non_const_value_ptr << std::endl; + + return 0; +} +``` + +In this example, we first create a `const` variable, `original_value`. Then we use `const_cast` to remove the constness of the variable and assign it to a non-const pointer, `non_const_value_ptr`. The `modifyVariable` function takes an `int*` as an argument and modifies the value pointed to by the pointer, which would not have been possible if we passed the original `const int` directly. Finally, we print the `original_value` and the `*non_const_value_ptr`, which shows that the value has been modified using `const_cast`. + +Please note that this example comes with some risks, as it touches undefined behavior. */ \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/102-dynamic-cast.md b/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/102-dynamic-cast.md index e6ee2f7cd..622f17f5d 100644 --- a/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/102-dynamic-cast.md +++ b/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/102-dynamic-cast.md @@ -1 +1,40 @@ -# Dynamic cast \ No newline at end of file +# Dynamic Cast + +`dynamic_cast` is a type of casting operator in C++ that is used specifically for polymorphism. It safely converts pointers and references of a base class to its derived class and checks the validity of the conversion during runtime. If the conversion is not valid (i.e., the object is not of the target type), it returns a null pointer instead of producing undefined behavior. Therefore, `dynamic_cast` can prevent potential crashes and errors when using polymorphism. + +Here is a basic example of how `dynamic_cast` can be used: + +```cpp +#include + +class BaseClass { + public: + virtual void display() { + std::cout << "BaseClass" << std::endl; + } +}; + +class DerivedClass : public BaseClass { + public: + void display() { + std::cout << "DerivedClass" << std::endl; + } +}; + +int main() { + BaseClass *basePtr = new DerivedClass(); // Upcasting + DerivedClass *derivedPtr; + + derivedPtr = dynamic_cast(basePtr); // Downcasting + if (derivedPtr) { + derivedPtr->display(); // Output: DerivedClass + } else { + std::cout << "Invalid type conversion."; + } + + delete basePtr; + return 0; +} +``` + +In this example, a pointer to a `DerivedClass` object is assigned to a `BaseClass` pointer (`basePtr`). Then, we attempt to downcast it back to a `DerivedClass` pointer using `dynamic_cast`. If the casting is successful, we can access the `DerivedClass` functionality through the new pointer (`derivedPtr`). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/103-reinterpret-cast.md b/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/103-reinterpret-cast.md index 500fd613d..f917ca5a2 100644 --- a/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/103-reinterpret-cast.md +++ b/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/103-reinterpret-cast.md @@ -1 +1,30 @@ -# Reinterpret cast \ No newline at end of file +# reinterpret_cast + +`reinterpret_cast` is a type of casting in C++ that allows you to change the type of a pointer or an integer without altering the representation of the data. It is generally used when the conversion required is too low-level or not supported by other casting methods, such as `static_cast`. + +Using `reinterpret_cast` should be handled with care, as it can lead to undefined behavior and severe problems if used incorrectly. + +Here's an example of usage: + +```cpp +#include + +int main() { + int num = 42; + int *num_ptr = # + + // Disguise the integer pointer as a char pointer + char *char_ptr = reinterpret_cast(num_ptr); + + for (size_t i = 0; i < sizeof(int); ++i) { + // Print the individual bytes of the integer as characters + std::cout << "Byte " << i << ": " << char_ptr[i] << std::endl; + } + + return 0; +} +``` + +In this example, we're using `reinterpret_cast` to change the type of a pointer from `int *` to `char *`, effectively treating the integer as an array of characters and printing each byte. + +Remember that when using `reinterpret_cast`, you should be cautious about dereferencing the converted pointers. The behavior can be unpredictable, and it can lead to issues, such as accessing memory regions that are not intended to be accessed. `reinterpret_cast` should be used sparingly and only when a low-level conversion is necessary. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/index.md b/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/index.md index 9dccbd068..3305b4eb3 100644 --- a/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/index.md +++ b/src/data/roadmaps/cpp/content/109-language-concepts/101-type-casting/index.md @@ -1 +1,44 @@ -# Type casting \ No newline at end of file +# Type Casting in C++ + +Type casting is the process of converting a value from one data type to another. In C++, there are four different methods of type casting: + +1. **C-style casting**: It is the syntax inherited from C, and it is done by simply putting the target data type in parentheses before the value to cast. + Example: + ```cpp + int a = 10; + float b = (float)a; // C-style cast from int to float + ``` + +2. **`static_cast`**: This is the most commonly used method for type casting in C++. It is performed at compile time, and you should use it when you have an explicit conversion between data types. + Example: + ```cpp + int a = 10; + float b = static_cast(a); // static_cast from int to float + ``` + +3. **`dynamic_cast`**: This method is specifically used for safely converting pointers and references between base and derived classes in a class hierarchy. + Example: + ```cpp + class Base {}; + class Derived : public Base {}; + + Base* base_ptr = new Derived(); + Derived* derived_ptr = dynamic_cast(base_ptr); // dynamic_cast from Base* to Derived* + ``` + +4. **`reinterpret_cast`**: This cast changes the type of a pointer, reference, or an integer value. It is also called a bitwise cast because it changes how the compiler interprets the underlying bits. Use `reinterpret_cast` only when you have a deep understanding of what you're doing, as it does not guarantee that the resulting value will be meaningful. + Example: + ```cpp + int* a = new int(42); + long b = reinterpret_cast(a); // reinterpret_cast from int* to long + ``` + +5. **`const_cast`**: This casting method is used to remove the `const` qualifier from a variable. It is generally not recommended, but can be useful in certain situations where you have no control over the constness of a variable. + Example: + ```cpp + const int a = 10; + int* ptr = const_cast(&a); // const_cast from const int* to int* + *ptr = 20; // Not recommended, use with caution + ``` + +Remember to use the right type of casting based on the specific situation and follow good programming practices in order to ensure a safe and efficient code. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/109-language-concepts/102-undefined-behavior.md b/src/data/roadmaps/cpp/content/109-language-concepts/102-undefined-behavior.md index 29dc7cb38..9ae459761 100644 --- a/src/data/roadmaps/cpp/content/109-language-concepts/102-undefined-behavior.md +++ b/src/data/roadmaps/cpp/content/109-language-concepts/102-undefined-behavior.md @@ -1 +1,39 @@ -# Undefined behavior \ No newline at end of file +# Undefined Behavior (UB) + +**Undefined Behavior** +--- + +Undefined behavior in C++ refers to a situation where a program's behavior cannot be predicted due to any violation of the language rules. It is a result of various factors like uninitialized variables, using pointers to deallocated memory, out-of-bounds memory access, etc. The C++ standard does not define the behavior in such cases, which means the compiler or the runtime system is free to handle these situations in any way it wants. + +Some common examples of Undefined Behavior are: + +1. **Uninitialized Variables**: Accessing the value of an uninitialized variable can lead to undefined behavior. The value of an uninitialized variable is arbitrary and depends on what was in the memory location before the variable was declared. + + ```cpp + int x; + int y = x + 5; // Undefined behavior since x is uninitialized + ``` + +2. **Out-of-bounds Memory Access**: Accessing memory outside the boundaries of an array or buffer may result in undefined behavior. + + ```cpp + int arr[5]; + int val = arr[5]; // Undefined behavior since the valid indices are 0 to 4 + ``` + +3. **Null Pointer Dereference**: Dereferencing a null pointer may lead to undefined behavior. + + ```cpp + int *ptr = nullptr; + int val = *ptr; // Undefined behavior since ptr is a null pointer + ``` + +4. **Division by Zero**: Performing a division operation by zero is undefined behavior in C++. + + ```cpp + int x = 5; + int y = 0; + int z = x / y; // Undefined behavior since division by zero is not allowed + ``` + +It is crucial to detect and fix the root cause of undefined behavior in your programs since it can lead to unpredictable results, data corruption, and security vulnerabilities. To mitigate undefined behavior, you can utilize tools like static code analyzers, dynamic analysis tools, and compiler options that help detect potential issues. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/109-language-concepts/103-adl.md b/src/data/roadmaps/cpp/content/109-language-concepts/103-adl.md index d0dee4aee..59f92a020 100644 --- a/src/data/roadmaps/cpp/content/109-language-concepts/103-adl.md +++ b/src/data/roadmaps/cpp/content/109-language-concepts/103-adl.md @@ -1 +1,32 @@ -# Adl \ No newline at end of file +# Argument Dependent Lookup (ADL) + +Argument Dependent Lookup (ADL) or Koenig Lookup is a mechanism in C++ that allows the compiler to search for the appropriate function to call based on the types of arguments provided. It is particularly helpful when using overloaded functions or operators in a namespace. + +ADL allows the compiler to find functions in the same namespace as the arguments, even if the function is not declared at the point of use or within the namespace provided. This is especially useful when working with templates or generic programming. + +### Example + +Consider the following example using a namespace and overloaded `operator<<()`: + +```cpp +namespace MyNamespace { + class MyClass { + public: + int value; + }; + + std::ostream& operator<<(std::ostream& os, const MyClass& obj) { + os << "MyClass: " << obj.value; + return os; + } +} + +int main() { + MyNamespace::MyClass obj; + obj.value = 42; + using std::cout; // Required to use 'cout' without fully qualifying it. + cout << obj << std::endl; // ADL is used to find the correct overloaded 'operator<<'. +} +``` + +In this example, when you call `cout << obj;` in `main()`, ADL is used to find the correct `operator<<()` in the `MyNamespace` namespace because the argument `obj` is of type `MyNamespace::MyClass`. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/109-language-concepts/104-name-mangling.md b/src/data/roadmaps/cpp/content/109-language-concepts/104-name-mangling.md index aeb8f1057..7f7fd12d4 100644 --- a/src/data/roadmaps/cpp/content/109-language-concepts/104-name-mangling.md +++ b/src/data/roadmaps/cpp/content/109-language-concepts/104-name-mangling.md @@ -1 +1,27 @@ -# Name mangling \ No newline at end of file +# Name Mangling + +Name mangling, also known as name decoration, is a technique used by compilers to encode additional information about the scope, type, linkage, or other identifying information of an identifier (function names, variable names, etc.) within its name. The primary purpose of name mangling is to support function overloading, which allows multiple functions with the same name but different parameter lists to coexist in a single program. + +In C++, the compiler generates a mangled name for each function and variable based on their scopes and types. The mangled name is usually formed by concatenating the original name, parameter types, and other information, often using a prefix or suffix. + +For example, suppose you have the following function: + +```cpp +int add(int a, int b) +{ + return a + b; +} +``` + +The compiler might generate a mangled name such as `_Z3addii`, which encodes the function name `add` and its two `int` parameters. + +The exact rules for name mangling are implementation and platform dependent. Different compilers may mangle names differently, which can lead to incompatibilities when attempting to link together object files or libraries compiled with different compilers. + +Some tools, such as c++filt (included in GCC and Clang), can be used to demangle a mangled name back to the original identifier, which can be useful when debugging or working with symbol tables. + +```sh +$ echo "_Z3addii" | c++filt +add(int, int) +``` + +In general, it is not necessary for you to understand the details of name mangling when writing code in C++, as the compiler handles it automatically. However, it can affect program behavior in some cases, such as when using external libraries or linking object files from different compilers. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/109-language-concepts/105-macros.md b/src/data/roadmaps/cpp/content/109-language-concepts/105-macros.md index a0715688a..ee62629db 100644 --- a/src/data/roadmaps/cpp/content/109-language-concepts/105-macros.md +++ b/src/data/roadmaps/cpp/content/109-language-concepts/105-macros.md @@ -1 +1,55 @@ -# Macros \ No newline at end of file +# C++ Macros + +Macros are preprocessing directives in C++ used by the preprocessor to perform text substitution. They are defined using the `#define` directive, followed by the macro name and the value to be substituted. + +Macros can be used to define constants, create function-like macros, or perform conditional compilation. + +### Constant Macros + +Constant macros are used to define symbolic constants for use in code. They do not use any memory and are replaced by the preprocessor before the compilation process. + +Example: + +```cpp +#define PI 3.14159 +``` + +This macro defines a symbolic constant `PI`. You can use it in your code as if it were a regular variable. + +```cpp +double circumference = 2 * PI * radius; +``` + +### Function-like Macros + +Function-like macros are similar to regular functions. They take a list of arguments and perform text substitution. + +Example: + +```cpp +#define SQUARE(x) ((x) * (x)) +``` + +This macro defines a function-like macro `SQUARE` that calculates the square of a number. + +```cpp +int square_of_five = SQUARE(5); // expands to ((5) * (5)) +``` + +### Conditional Compilation + +Macros can be used for conditional compilation using the `#ifdef`, `#ifndef`, `#if`, `#else`, `#elif`, and `#endif` directives. + +Example: + +```cpp +#define DEBUG_MODE + +#ifdef DEBUG_MODE + // Code to be compiled only in debug mode +#else + // Code to be compiled only if DEBUG_MODE is not defined +#endif +``` + +This example demonstrates how you can use macros to control the parts of code that are being compiled, depending on the presence or absence of a macro definition. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/110-stl/101-iostream.md b/src/data/roadmaps/cpp/content/110-stl/101-iostream.md index d0875510a..0d6f4c7aa 100644 --- a/src/data/roadmaps/cpp/content/110-stl/101-iostream.md +++ b/src/data/roadmaps/cpp/content/110-stl/101-iostream.md @@ -1 +1,48 @@ -# Iostream \ No newline at end of file +# iostream + +`iostream` is a header in the C++ Standard Library that provides functionality for basic input and output (I/O) operations. The I/O streams facilitate communication between your program and various sources, such as the console, files, or other programs. + +`iostream` includes the following classes: + +- `istream`: for input operations from an input source. +- `ostream`: for output operations to an output target. +- `iostream`: a combination of `istream` and `ostream` for both input and output operations. + +These classes inherit from base classes `ios` and `ios_base`. + +Additionally, `iostream` defines several objects that are instances of these classes and represent the standard input and output streams: + +- `cin`: an `istream` object to read from the standard input, typically corresponding to the keyboard. +- `cout`: an `ostream` object to write to the standard output, typically the console. +- `cerr`: an `ostream` object to write to the standard error output, typically used for displaying error messages. +- `clog`: an `ostream` object, similar to `cerr`, but its output can be buffered. + +Here are some code examples on using `iostream` for input and output operations: + +```cpp +#include + +int main() { + int a; + std::cout << "Enter a number: "; + std::cin >> a; + std::cout << "You entered: " << a << std::endl; + return 0; +} +``` + +```cpp +#include + +int main() { + std::cerr << "An error occurred." << std::endl; + std::clog << "Logging information." << std::endl; + return 0; +} +``` + +Remember to include the `iostream` header when using these features: + +```cpp +#include +``` \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/110-stl/104-multithreading.md b/src/data/roadmaps/cpp/content/110-stl/104-multithreading.md index 0e302e28b..34ae287ad 100644 --- a/src/data/roadmaps/cpp/content/110-stl/104-multithreading.md +++ b/src/data/roadmaps/cpp/content/110-stl/104-multithreading.md @@ -1 +1,77 @@ -# Multithreading \ No newline at end of file +# Multithreading in C++ + +Multithreading is the concurrent execution of multiple threads within a single process or program. It improves the performance and efficiency of an application by allowing multiple tasks to be executed in parallel. + +In C++, multithreading support is available through the `thread` library introduced in the C++11 standard. + +### Basic Thread Creation + +To create a new thread, include the `` header file and create an instance of `std::thread` that takes a function as an argument. The function will be executed in a new thread. + +```cpp +#include +#include + +void my_function() { + std::cout << "This function is executing in a separate thread" << std::endl; +} + +int main() { + std::thread t(my_function); + t.join(); // waits for the thread to complete + return 0; +} +``` + +### Thread with Arguments + +You can pass arguments to the thread function by providing them as additional arguments to the `std::thread` constructor. + +```cpp +#include +#include + +void print_sum(int a, int b) { + std::cout << "The sum is: " << a + b << std::endl; +} + +int main() { + std::thread t(print_sum, 3, 5); + t.join(); + return 0; +} +``` + +### Mutex and Locks + +When multiple threads access shared resources, there is a possibility of a data race. To avoid this, use mutex and locks to synchronize shared resource access. + +```cpp +#include +#include +#include + +std::mutex mtx; + +void print_block(int n, char c) { + { + std::unique_lock locker(mtx); + for (int i = 0; i < n; ++i) { + std::cout << c; + } + std::cout << std::endl; + } +} + +int main() { + std::thread t1(print_block, 50, '*'); + std::thread t2(print_block, 50, '$'); + + t1.join(); + t2.join(); + + return 0; +} +``` + +This short introduction should help you get started with basic multithreading techniques in C++. There is a lot more to learn, such as thread pools, condition variables, and atomic operations for advanced synchronization and performance tuning. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/111-templates/100-variadic-templates.md b/src/data/roadmaps/cpp/content/111-templates/100-variadic-templates.md index 2047c83c3..d8a1da932 100644 --- a/src/data/roadmaps/cpp/content/111-templates/100-variadic-templates.md +++ b/src/data/roadmaps/cpp/content/111-templates/100-variadic-templates.md @@ -1 +1,71 @@ -# Variadic templates \ No newline at end of file +# Variadic Templates + +Variadic templates are a feature in C++11 that allows you to define a template with a variable number of arguments. This is especially useful when you need to write a function or class that can accept different numbers and types of arguments. + +### Syntax + +The syntax for variadic templates is very simple. To define a variadic template, use the `...` (ellipsis) notation: + +```cpp +template +``` + +This notation represents a parameter pack, which can contain zero or more arguments. You can use this parameter pack as a variable list of template parameters in your template definition. + +### Examples + +#### Summing Multiple Arguments Using Variadic Templates + +```cpp +#include + +// Base case for recursion +template +T sum(T t) { + return t; +} + +// Variadic template +template +T sum(T t, Args... args) { + return t + sum(args...); +} + +int main() { + int result = sum(1, 2, 3, 4, 5); // expands to 1 + 2 + 3 + 4 + 5 + std::cout << "The sum is: " << result << std::endl; + + return 0; +} +``` + +#### Tuple Class Using Variadic Templates + +```cpp +template +class Tuple; + +// Base case: empty tuple +template <> +class Tuple<> {}; + +// Recursive case: Tuple with one or more elements +template +class Tuple : public Tuple { + public: + Tuple(Head head, Tail... tail) : Tuple(tail...), head_(head) {} + + Head head() const { return head_; } + + private: + Head head_; +}; + +int main() { + Tuple tuple(1, 2.0f, 3.0); + std::cout << "First element: " << tuple.head() << std::endl; + return 0; +} +``` + +Please note that the examples shown are for educational purposes and might not be the most efficient or production-ready implementations. With C++17 and onward, there are even more concise ways to handle variadic templates, like using fold expressions. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/111-templates/101-template-specialization/100-full.md b/src/data/roadmaps/cpp/content/111-templates/101-template-specialization/100-full.md index 131767a9b..a80d4a82c 100644 --- a/src/data/roadmaps/cpp/content/111-templates/101-template-specialization/100-full.md +++ b/src/data/roadmaps/cpp/content/111-templates/101-template-specialization/100-full.md @@ -1 +1,46 @@ -# Full \ No newline at end of file +# Full Template Specialization + +Full template specialization allows you to provide a specific implementation, or behavior, for a template when used with a certain set of type parameters. It is useful when you want to handle special cases or optimize your code for specific types. + +### Syntax +To create a full specialization of a template, you need to define the specific type for which the specialization should happen. The syntax looks as follows: + +```cpp +template <> //Indicates that this is a specialization +className //The specialized class for the specific type +``` + +### Example +Consider the following example to demonstrate full template specialization: + +```cpp +// Generic template +template +class MyContainer { +public: + void print() { + std::cout << "Generic container." << std::endl; + } +}; + +// Full template specialization for int +template <> +class MyContainer { +public: + void print() { + std::cout << "Container for integers." << std::endl; + } +}; + +int main() { + MyContainer d; + MyContainer i; + + d.print(); // Output: Generic container. + i.print(); // Output: Container for integers. + + return 0; +} +``` + +In this example, we defined a generic `MyContainer` template class along with a full specialization for `int` type. When we use the container with the `int` type, the specialized implementation's `print` method is called. For other types, the generic template implementation will be used. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/111-templates/101-template-specialization/101-partial.md b/src/data/roadmaps/cpp/content/111-templates/101-template-specialization/101-partial.md index febf47d1e..cc9e0ad9c 100644 --- a/src/data/roadmaps/cpp/content/111-templates/101-template-specialization/101-partial.md +++ b/src/data/roadmaps/cpp/content/111-templates/101-template-specialization/101-partial.md @@ -1 +1,59 @@ -# Partial \ No newline at end of file +# Partial Template Specialization + +Partial template specialization is a concept in C++ templates, which allows you to specialize a template for a subset of its possible type arguments. It is particularly useful when you want to provide a customized implementation for a particular group of types without having to define separate specializations for all types in that group. + +Partial template specialization is achieved by providing a specialization of a template with a new set of template parameters. This new template will be chosen when the compiler deduces the types that match the partial specialization. + +Here is a code example that demonstrates partial template specialization: + +```cpp +// Primary template +template +struct MyTemplate { + static const char* name() { + return "General case"; + } +}; + +// Partial specialization for pointers +template +struct MyTemplate { + static const char* name() { + return "Partial specialization for pointers"; + } +}; + +// Full specialization for int +template <> +struct MyTemplate { + static const char* name() { + return "Full specialization for int"; + } +}; + +int main() { + MyTemplate t1; // General case + MyTemplate t2; // Partial specialization for pointers + MyTemplate t3; // Full specialization for int + + std::cout << t1.name() << std::endl; + std::cout << t2.name() << std::endl; + std::cout << t3.name() << std::endl; + + return 0; +} +``` + +In the example above, we have defined a primary template `MyTemplate` with a single type parameter `T`. We then provide a partial template specialization for pointer types by specifying `MyTemplate`. This means that the partial specialization will be chosen when the type argument is a pointer type. + +Lastly, we provide a full specialization for the `int` type by specifying `MyTemplate`. This will be chosen when the type argument is `int`. + +When running this example, the output will be: + +``` +General case +Partial specialization for pointers +Full specialization for int +``` + +This demonstrates that the partial specialization works as expected, and is chosen for pointer types, while the full specialization is chosen for the `int` type. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/111-templates/102-type-traits.md b/src/data/roadmaps/cpp/content/111-templates/102-type-traits.md index b4062d4f6..bc92a6110 100644 --- a/src/data/roadmaps/cpp/content/111-templates/102-type-traits.md +++ b/src/data/roadmaps/cpp/content/111-templates/102-type-traits.md @@ -1 +1,57 @@ -# Type traits \ No newline at end of file +# Type Traits + +Type Traits are a set of template classes in C++ that help in getting the information about the type's properties, behavior, or characteristics. They can be found in the `` header file. By using Type Traits, you can adapt your code depending on the properties of a given type, or even enforce specific properties for your type parameters in template code. + +Some common type traits are: + +- `std::is_pointer`: Checks if a given type is a pointer type. +- `std::is_arithmetic`: Checks if the given type is an arithmetic type. +- `std::is_function`: Checks if the given type is a function type. +- `std::decay`: Applies decltype rules to the input type ( strips references, cv-qualifiers, etc. ). + +### Usage + +You can use type traits like this: + +```cpp +#include +#include + +int main() { + int a; + int* a_ptr = &a; + + std::cout << "Is 'a' a pointer? " << std::boolalpha << std::is_pointer::value << std::endl; + std::cout << "Is 'a_ptr' a pointer? " << std::boolalpha << std::is_pointer::value << std::endl; + + return 0; +} +``` + +### Composing Type Traits + +Some type traits help you compose other traits or modify them, such as: + +- `std::conditional`: If a given boolean value is true, use type A; otherwise, use type B. +- `std::enable_if`: If a given boolean value is true, use type A; otherwise, there is no nested type. + +```cpp +#include +#include + +template +typename std::enable_if::value, T>::type find_max(T a, T b) { + return a > b ? a : b; +} + +int main() { + int max = find_max(10, 20); + std::cout << "Max: " << max << std::endl; + + return 0; +} +``` + +In this example, the `find_max` template function is only defined when T is an arithmetic type (e.g., int, float, double). This prevents unintended usage of the `find_max` function with non-arithmetic types. + +Overall, type traits are a powerful tool to create more generic, extensible, and efficient C++ code, providing a way to query and adapt your code based on type characteristics. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/111-templates/103-finae.md b/src/data/roadmaps/cpp/content/111-templates/103-finae.md index dff53923e..dafdd80e4 100644 --- a/src/data/roadmaps/cpp/content/111-templates/103-finae.md +++ b/src/data/roadmaps/cpp/content/111-templates/103-finae.md @@ -1 +1,36 @@ -# Finae \ No newline at end of file +# SFINAE (Substitution Failure Is Not An Error) + +SFINAE is a principle in C++ template metaprogramming that allows the compiler to select the appropriate function or class when a specific template specialization fails during substitution. The term "substitution failure" refers to the process where the compiler tries to substitute template arguments into a function template or class template. If the substitution causes an error, the compiler won't consider that specific specialization as a candidate and will continue searching for a valid one. + +The key idea behind SFINAE is that if a substitution error occurs, it is silently ignored, and the compiler continues to explore other template specializations or overloads. This allows you to write more flexible and generic code, as it enables you to have multiple specializations for different scenarios. + +### Code Example + +Here's an example that demonstrates SFINAE in action: + +```cpp +#include +#include + +template ::value>> +void foo(T t) { + std::cout << "Called when T is arithmetic" << std::endl; +} + +template ::value>> +void foo(T t) { + std::cout << "Called when T is not arithmetic" << std::endl; +} + +int main() { + int a = 5; + foo(a); // output: Called when T is arithmetic + + std::string s = "example"; + foo(s); // output: Called when T is not arithmetic +} +``` + +In this example, we define two `foo` function template specializations. The first one is enabled when `T` is an arithmetic type, while the second one is enabled when `T` is not an arithmetic type. The `std::enable_if_t` inside the template parameter list allows us to control which specialization is valid for a given type of `T`. + +When calling `foo(a)` with an integer, the first specialization is selected, and when calling `foo(s)` with a string, the second specialization is selected. If there is no valid specialization, the code would fail to compile. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/111-templates/index.md b/src/data/roadmaps/cpp/content/111-templates/index.md index fd5397edd..569b7aac0 100644 --- a/src/data/roadmaps/cpp/content/111-templates/index.md +++ b/src/data/roadmaps/cpp/content/111-templates/index.md @@ -1 +1,76 @@ -# Templates \ No newline at end of file +# C++ Templates + +Templates in C++ are a powerful feature that allows you to write generic code, meaning that you can write a single function or class that can work with different data types. This means you do not need to write separate functions or classes for each data type you want to work with. + +### Template Functions + +To create a template function, you use the `template` keyword followed by the type parameters or placeholders enclosed in angle brackets (`< >`). Then, you define your function as you normally would, using the type parameters to specify the generic types. + +Here's an example of a simple template function that takes two arguments and returns the larger of the two: + +```cpp +template +T max(T a, T b) { + return (a > b) ? a : b; +} +``` + +To use this function, you can either explicitly specify the type parameter: + +```cpp +int result = max(10, 20); +``` + +Or, you can let the compiler deduce the type for you: + +```cpp +int result = max(10, 20); +``` + +### Template Classes + +Similarly, you can create template classes using the `template` keyword. Here's an example of a simple template class that represents a pair of values: + +```cpp +template +class Pair { +public: + T1 first; + T2 second; + + Pair(T1 first, T2 second) : first(first), second(second) {} +}; +``` + +To use this class, you need to specify the type parameters when creating an object: + +```cpp +Pair pair(1, "Hello"); +``` + +### Template Specialization + +Sometimes, you may need special behavior for a specific data type. In this case, you can use template specialization. For example, you can specialize the `Pair` class for a specific type, like `char`: + +```cpp +template <> +class Pair { +public: + char first; + char second; + + Pair(char first, char second) : first(first), second(second) { + // Special behavior for characters (e.g., convert to uppercase) + this->first = std::toupper(this->first); + this->second = std::toupper(this->second); + } +}; +``` + +Now, when you create a `Pair` object with `char` template arguments, the specialized behavior will be used: + +```cpp +Pair charPair('a', 'b'); +``` + +In summary, templates in C++ allow you to write generic functions and classes that can work with different data types, reducing code duplication and making your code more flexible and reusable. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/112-idioms/100-raii.md b/src/data/roadmaps/cpp/content/112-idioms/100-raii.md index 3ceab2ba0..c7524d7c6 100644 --- a/src/data/roadmaps/cpp/content/112-idioms/100-raii.md +++ b/src/data/roadmaps/cpp/content/112-idioms/100-raii.md @@ -1 +1,73 @@ -# Raii \ No newline at end of file +# RAII (Resource Acquisition Is Initialization) + +RAII is a popular idiom in C++ that focuses on using the object's life cycle to manage resources. It encourages binding the resource lifetime to the scope of a corresponding object so that it's automatically acquired when an object is created and released when the object is destroyed. This helps in simplifying the code, avoiding leaks and managing resources efficiently. + +### Code Examples + +Here's an example of using RAII to manage resources, specifically a dynamically allocated array: + +```cpp +class ManagedArray { +public: + ManagedArray(size_t size) : size_(size), data_(new int[size]) { + } + + ~ManagedArray() { + delete[] data_; + } + + // Access function + int& operator [](size_t i) { + return data_[i]; + } + +private: + size_t size_; + int* data_; +}; +``` + +Usages: + +```cpp +{ + ManagedArray arr(10); + arr[0] = 42; + + // No need to explicitly free memory, it will be automatically released when arr goes out of scope. +} +``` + +Another common use case is managing a mutex lock: + +```cpp +class Lock { +public: + Lock(std::mutex& mtx) : mutex_(mtx) { + mutex_.lock(); + } + + ~Lock() { + mutex_.unlock(); + } + +private: + std::mutex& mutex_; +}; +``` + +Usages: + +```cpp +std::mutex some_mutex; + +void protected_function() { + Lock lock(some_mutex); + + // Do some work that must be synchronized + + // No need to explicitly unlock the mutex, it will be automatically unlocked when lock goes out of scope. +} +``` + +In both examples, the constructor acquires the resource (memory for the array and the lock for the mutex), and the destructor takes care of releasing them. This way, the resource management is tied to the object's lifetime, and the resource is correctly released even in case of an exception being thrown. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/112-idioms/101-pimpl.md b/src/data/roadmaps/cpp/content/112-idioms/101-pimpl.md index b4a4ec06c..4c6890c15 100644 --- a/src/data/roadmaps/cpp/content/112-idioms/101-pimpl.md +++ b/src/data/roadmaps/cpp/content/112-idioms/101-pimpl.md @@ -1 +1,49 @@ -# Pimpl \ No newline at end of file +# Pimpl Idiom + +Pimpl (Pointer-to-Implementation) idiom, also known as a private class data, compiler firewall, or handle classes, is a technique used in C++ to hide the implementation details of a class by using a forward declaration to a private structure or class, keeping the public interface of the class clean, and reducing compile-time dependencies. + +### Implementation + +Here is a simple example illustrating the Pimpl idiom: + +**my_class.h** +```cpp +class MyClass_Impl; // forward declaration + +class MyClass +{ +public: + MyClass(); + ~MyClass(); + void some_method(); + +private: + MyClass_Impl *pimpl; // pointer to the implementation +}; +``` + +**my_class.cpp** +```cpp +#include "my_class.h" +#include + +class MyClass_Impl // the actual implementation +{ +public: + void some_method() + { + std::cout << "Implementation method called!" << std::endl; + } +}; + +MyClass::MyClass() : pimpl(new MyClass_Impl()) {} // constructor + +MyClass::~MyClass() { delete pimpl; } // destructor + +void MyClass::some_method() +{ + pimpl->some_method(); // delegation to the implementation +} +``` + +Now, all the public methods of `MyClass` will delegate the calls to the corresponding methods of `MyClass_Impl`. By doing this, you can hide the details of class implementation, reduce the compile-time dependencies, and ease the maintenance of your code. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/112-idioms/102-crtp.md b/src/data/roadmaps/cpp/content/112-idioms/102-crtp.md index 22bf82040..e09f1ed22 100644 --- a/src/data/roadmaps/cpp/content/112-idioms/102-crtp.md +++ b/src/data/roadmaps/cpp/content/112-idioms/102-crtp.md @@ -1 +1,48 @@ -# Crtp \ No newline at end of file +# CRTP + +**Curiously Recurring Template Pattern (CRTP)** + +The Curiously Recurring Template Pattern (CRTP) is a C++ idiom that involves a class template being derived from its own specialization. This pattern allows for the creation of static polymorphism, which differs from regular runtime polymorphism that relies on virtual functions and inheritance. + +CRTP is usually employed when you want to customize certain behavior in the base class without adding the overhead of a virtual function call. In short, CRTP can be used for achieving compile-time polymorphism without the runtime performance cost. + +Here's an example demonstrating CRTP: + +```cpp +template +class Base { +public: + void interface() { + static_cast(this)->implementation(); + } + + void implementation() { + std::cout << "Default implementation in Base" << std::endl; + } +}; + +class Derived1 : public Base { +public: + void implementation() { + std::cout << "Custom implementation in Derived1" << std::endl; + } +}; + +class Derived2 : public Base { + // No custom implementation, so Base::implementation will be used. +}; + +int main() { + Derived1 d1; + d1.interface(); // Output: "Custom implementation in Derived1" + + Derived2 d2; + d2.interface(); // Output: "Default implementation in Base" + + return 0; +} +``` + +In this example, the `Base` class is a template that takes a single type parameter. `Derived1` and `Derived2` are derived from their respective specialization of `Base`. CRTP is employed to allow custom implementations of the `implementation()` function in derived classes while providing a default behavior in the `Base` class. The `interface()` function in the `Base` class is a template for the derived class's behavior and calls the corresponding `implementation()` function based on the static type. + +This pattern enables you to override certain behavior in derived classes with additional functionality, all while avoiding the overhead of virtual function calls and, in turn, achieving a higher degree of efficiency at runtime. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/112-idioms/103-non-copyable.md b/src/data/roadmaps/cpp/content/112-idioms/103-non-copyable.md index d20df0c97..743fe5b60 100644 --- a/src/data/roadmaps/cpp/content/112-idioms/103-non-copyable.md +++ b/src/data/roadmaps/cpp/content/112-idioms/103-non-copyable.md @@ -1 +1,31 @@ -# Non copyable \ No newline at end of file +# Non-Copyable + +The non-copyable idiom is a C++ design pattern that prevents objects from being copied or assigned. It's usually applied to classes that manage resources, like file handles or network sockets, where copying the object could cause issues like resource leaks or double deletions. + +To make a class non-copyable, you need to delete the copy constructor and the copy assignment operator. This can be done explicitly in the class declaration, making it clear to other programmers that copying is not allowed. + +Here's an example of how to apply the non-copyable idiom to a class: + +```cpp +class NonCopyable { +public: + NonCopyable() = default; + ~NonCopyable() = default; + + // Delete the copy constructor + NonCopyable(const NonCopyable&) = delete; + + // Delete the copy assignment operator + NonCopyable& operator=(const NonCopyable&) = delete; +}; +``` + +To use the idiom, simply inherit from the `NonCopyable` class: + +```cpp +class MyClass : private NonCopyable { + // MyClass is now non-copyable +}; +``` + +This ensures that any attempt to copy or assign objects of `MyClass` will result in a compilation error, thus preventing unwanted behavior. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/112-idioms/104-erase-remove.md b/src/data/roadmaps/cpp/content/112-idioms/104-erase-remove.md index 7ec74ac9a..562d476f2 100644 --- a/src/data/roadmaps/cpp/content/112-idioms/104-erase-remove.md +++ b/src/data/roadmaps/cpp/content/112-idioms/104-erase-remove.md @@ -1 +1,36 @@ -# Erase remove \ No newline at end of file +# Erase-remove idiom + +The erase-remove idiom is a common C++ technique to efficiently remove elements from a container, particularly from standard sequence containers like `std::vector`, `std::list`, and `std::deque`. It leverages the standard library algorithms `std::remove` (or `std::remove_if`) and the member function `erase()`. + +The idiom consists of two steps: +1. `std::remove` (or `std::remove_if`) moves the elements to be removed towards the end of the container and returns an iterator pointing to the first element to remove. +2. `container.erase()` removes the elements from the container using the iterator obtained in the previous step. + +Here's an example: + +```cpp +#include +#include +#include + +int main() { + std::vector numbers = {1, 3, 2, 4, 3, 5, 3}; + + // Remove all occurrences of 3 from the vector. + numbers.erase(std::remove(numbers.begin(), numbers.end(), 3), numbers.end()); + + for (int number : numbers) { + std::cout << number << " "; + } + + return 0; +} +``` + +Output: + +``` +1 2 4 5 +``` + +In this example, we used the `std::remove` algorithm to remove all occurrences of the number 3 from the `std::vector numbers`. After the removal, the vector contains only 1, 2, 4, and 5, as the output shows. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/112-idioms/105-copy-swap.md b/src/data/roadmaps/cpp/content/112-idioms/105-copy-swap.md index 428bc8960..89e8da83e 100644 --- a/src/data/roadmaps/cpp/content/112-idioms/105-copy-swap.md +++ b/src/data/roadmaps/cpp/content/112-idioms/105-copy-swap.md @@ -1 +1,37 @@ -# Copy swap \ No newline at end of file +# Copy and Swap + +Copy-swap is a C++ idiom that leverages the copy constructor and swap function to create an assignment operator. It follows a simple, yet powerful paradigm: create a temporary copy of the right-hand side object, and swap its contents with the left-hand side object. + +Here's a brief summary: + +1. **Copy**: Create a local copy of the right-hand side object. This step leverages the copy constructor, providing exception safety and code reuse. +2. **Swap**: Swap the contents of the left-hand side object with the temporary copy. This step typically involves swapping internal pointers or resources, without needing to copy the full contents again. +3. **Destruction**: Destroy the temporary copy. This happens upon the exit of the assignment operator. + +Here's a code example for a simple `String` class: + +```cpp +class String { + // ... rest of the class ... + + String(const String& other); + + void swap(String& other) { + using std::swap; // for arguments-dependent lookup (ADL) + swap(size_, other.size_); + swap(buffer_, other.buffer_); + } + + String& operator=(String other) { + swap(other); + return *this; + } +}; +``` + +Using the copy-swap idiom: +1. The right-hand side object is copied when passed by value to the assignment operator. +2. The left-hand side object's contents are swapped with the temporary copy. +3. The temporary copy is destroyed, releasing any resources that were previously held by the left-hand side object. + +This approach simplifies the implementation and provides strong exception safety, while reusing the copy constructor and destructor code. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/112-idioms/106-copy-write.md b/src/data/roadmaps/cpp/content/112-idioms/106-copy-write.md index 5c0f911b2..9aa6e53ac 100644 --- a/src/data/roadmaps/cpp/content/112-idioms/106-copy-write.md +++ b/src/data/roadmaps/cpp/content/112-idioms/106-copy-write.md @@ -1 +1,43 @@ -# Copy write \ No newline at end of file +# Copy-Write Idiom + +The Copy-Write idiom, sometimes called the Copy-on-Write (CoW) or "lazy copying" idiom, is a technique used in programming to minimize the overhead of copying large objects. It helps in reducing the number of actual copy operations by using shared references to objects and only copying the data when it's required for modification. + +Let's understand this with a simple example: + +```cpp +#include +#include + +class MyString { +public: + MyString(const std::string &str) : data(std::make_shared(str)) {} + + // Use the same shared data for copying. + MyString(const MyString &other) : data(other.data) { + std::cout << "Copied using the Copy-Write idiom." << std::endl; + } + + // Make a copy only if we want to modify the data. + void write(const std::string &str) { + // Check if there's more than one reference. + if(!data.unique()) { + data = std::make_shared(*data); + std::cout << "Copy is actually made for writing." << std::endl; + } + *data = str; + } + +private: + std::shared_ptr data; +}; + +int main() { + MyString str1("Hello"); + MyString str2 = str1; // No copy operation, just shared references. + + str1.write("Hello, World!"); // This is where the actual duplication happens. + return 0; +} +``` + +In this example, we have a class `MyString` that simulates the Copy-Write idiom. When a `MyString` object is created, it constructs a `shared_ptr` pointing to a string. When a `MyString` object is copied, it does not perform any actual copy operation, but simply increases the reference count of the shared object. Finally, when the `write` function is called, it checks if there's more than one reference to the data and if so, it actually creates a new copy and updates the reference. This way, unnecessary copies can be avoided until they are actually needed for modification. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/113-standards/101-cpp17.md b/src/data/roadmaps/cpp/content/113-standards/101-cpp17.md index cf47cfffb..594cc37b1 100644 --- a/src/data/roadmaps/cpp/content/113-standards/101-cpp17.md +++ b/src/data/roadmaps/cpp/content/113-standards/101-cpp17.md @@ -1 +1,61 @@ -# Cpp17 \ No newline at end of file +# C++17 + +C++17, also known as C++1z, is the version of the C++ programming language published in December 2017. It builds upon the previous standard, C++14, and adds various new features and enhancements to improve the language's expressiveness, performance, and usability. + +### Key Features: +- If-init-statement: Introduces a new syntax for writing conditions with scope inside if and switch statements. +```cpp +if(auto it = map.find(key); it != map.end()) +{ + // Use it +} +``` + +- Structured Binding Declarations: Simplify the process of unpacking a tuple, pair, or other aggregate types. +```cpp +map data; +auto [iter, success] = data.emplace("example", 42); +``` + +- Inline variables: Enables `inline` keyword for variables and allows single definition of global and class static variables in header files. +```cpp +inline int globalVar = 0; +``` + +- Folds expressions: Introduce fold expressions for variadic templates. +```cpp +template +auto sum(Ts... ts) +{ + return (ts + ...); +} +``` + +- constexpr if statement: Allows conditional compilation during compile time. +```cpp +template +auto get_value(T t) +{ + if constexpr (std::is_pointer_v) + { + return *t; + } + else + { + return t; + } +} +``` + +- Improved lambda expression: Allows lambda to capture a single object without changing its type or constness. +```cpp +auto func = [x = std::move(obj)] { /* use x */ }; +``` + +- Standard file system library: `std::filesystem` as a standardized way to manipulate paths, directories, and files. + +- New Standard Library additions: `` (non-owning string reference), `` (type-safe discrimination union), `` (optional value wrapper), `` (type-safe sum type), and `` (library for polymorphic allocators). + +- Parallel Algorithms: Adds support for parallel execution of Standard Library algorithms. + +This is a brief summary of the key features of C++17; it includes more features and library updates. For a complete list, you can refer to the [full list of C++17 features and changes](https://en.cppreference.com/w/cpp/17). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/113-standards/104-cpp0x.md b/src/data/roadmaps/cpp/content/113-standards/104-cpp0x.md index f0e4989a6..2cf9e93f1 100644 --- a/src/data/roadmaps/cpp/content/113-standards/104-cpp0x.md +++ b/src/data/roadmaps/cpp/content/113-standards/104-cpp0x.md @@ -1 +1,74 @@ -# Cpp0x \ No newline at end of file +# C++0x + +`cpp0x` refers to the working name for [C++11](https://en.cppreference.com/w/cpp/11), which was previously known as C++0x before its final release. C++11 is a major revision of the C++ language standard, published in 2011, and brought several new features and improvements to the language. + +Some of the notable features in C++11 include: + +- **Auto** keyword for automatic type inference. + + ```cpp + auto i = 42; // i is an int + auto s = "hello"; // s is a const char* + ``` + +- **Range-based for loop** for easier iteration over containers. + + ```cpp + std::vector vec = {1, 2, 3}; + for (int i : vec) { + std::cout << i << std::endl; + } + ``` + +- **Lambda functions** for creating anonymous functions. + + ```cpp + auto add = [](int a, int b) { return a + b; }; + int result = add(3, 4); // result is 7 + ``` + +- **nullptr** for representing null pointer values, instead of using `NULL`. + + ```cpp + int* p = nullptr; + ``` + +- **Rvalue references and move semantics** to optimize the handling of temporary objects. + + ```cpp + std::string str1 = "hello"; + std::string str2 = std::move(str1); // move the content of str1 to str2 + ``` + +- **Variadic templates** for creating templates that take a variable number of arguments. + + ```cpp + template + void printArgs(Args... args) { + // function body + } + ``` + +- **Static assertions** for compile-time assertions. + + ```cpp + static_assert(sizeof(int) == 4, "This code requires int to be 4 bytes."); + ``` + +- **Thread support** for multithreading programming. + + ```cpp + #include + + void my_function() { + // thread function body + } + + int main() { + std::thread t(my_function); + t.join(); + return 0; + } + ``` + +These are just a few examples of the many new features introduced in C++11. For a comprehensive list, you can refer to the [C++11 documentation](https://en.cppreference.com/w/cpp/11). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/114-debuggers/101-debugger-symbols.md b/src/data/roadmaps/cpp/content/114-debuggers/101-debugger-symbols.md index f58d07cf9..3bd925197 100644 --- a/src/data/roadmaps/cpp/content/114-debuggers/101-debugger-symbols.md +++ b/src/data/roadmaps/cpp/content/114-debuggers/101-debugger-symbols.md @@ -1 +1,43 @@ -# Debugger symbols \ No newline at end of file +# Debugger Symbols + +Debugger symbols are additional information embedded within the compiled program's binary code, that help debuggers in understanding the structure, source code, and variable representations at a particular point in the execution process. + +There are generally two types of debugging symbols: + +1. **Internal Debugging Symbols**: These symbols reside within the compiled binary code itself. When using internal debugging symbols, it is essential to note that the size of the binary increases, which may not be desirable for production environments. + +2. **External Debugging Symbols**: The debugging symbols are kept in separate files apart from the binary code, usually with file extensions such as `.pdb` (Program Database) in Windows or `.dSYM` (DWARF Symbol Information) in macOS. + +### Generating Debugger Symbols + +To generate debugger symbols in C++, you need to specify specific options during the compilation process. We will use `g++` compiler as an example. + +**Internal Debugging Symbols (g++)** + +To create a debug build with internal debugging symbols, use the `-g` flag: + +```bash +g++ -g -o my_program my_program.cpp +``` + +This command compiles `my_program.cpp` into an executable named `my_program` with internal debugging symbols. + +**External Debugging Symbols (g++)** + +In case you want to generate a separate file containing debugging symbols, you can use the `-gsplit-dwarf` flag: + +```bash +g++ -g -gsplit-dwarf -o my_program my_program.cpp +``` + +This command compiles `my_program.cpp` into an executable named `my_program` and generates a separate file named `my_program.dwo` containing the debugging symbols. + +When sharing your compiled binary to end-users, you can remove the debugging symbols using the `strip` command: + +```bash +strip --strip-debug my_program +``` + +This command removes internal debug symbols, resulting in a smaller binary size while keeping the `.dwo` file for debugging purposes when needed. + +Remember that the availability and syntax of these options may vary between different compilers and platforms. Be sure to consult your compiler's documentation to ensure proper usage of the debugging options. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/114-debuggers/103-gdb.md b/src/data/roadmaps/cpp/content/114-debuggers/103-gdb.md index dfd0c4c21..343fa16de 100644 --- a/src/data/roadmaps/cpp/content/114-debuggers/103-gdb.md +++ b/src/data/roadmaps/cpp/content/114-debuggers/103-gdb.md @@ -1 +1,81 @@ -# Gdb \ No newline at end of file +# GDB: GNU Debugger + +GDB, or the GNU Project Debugger, is a powerful command-line debugger used primarily for C, C++, and other languages. It can help you find runtime errors, examine the program's execution state, and manipulate the flow to detect and fix bugs easily. + +### Getting started with GDB + +To start using GDB, you first need to compile your code with the `-g` flag, which includes debugging information in the executable: + +```sh +g++ -g myfile.cpp -o myfile +``` + +Now, you can load your compiled program into GDB: + +```sh +gdb myfile +``` + +### Basic GDB Commands + +Here are some common GDB commands you'll find useful when debugging: + +- `run`: Start your program. +- `break [function/line number]`: Set a breakpoint at the specified function or line. +- `continue`: Continue the program execution after stopping on a breakpoint. +- `next`: Execute the next line of code, stepping over function calls. +- `step`: Execute the next line of code, entering function calls. +- `print [expression]`: Evaluate an expression in the current context and display its value. +- `backtrace`: Show the current call stack. +- `frame [frame-number]`: Switch to a different stack frame. +- `quit`: Exit GDB. + +### Example Usage + +Suppose you have a simple `cpp` file called `example.cpp`: + +```cpp +#include + +void my_function(int i) { + std::cout << "In my_function with i = " << i << std::endl; +} + +int main() { + for (int i = 0; i < 5; ++i) { + my_function(i); + } + return 0; +} +``` + +First, compile the code with debugging symbols: + +```sh +g++ -g example.cpp -o example +``` + +Start GDB and load the `example` program: + +```sh +gdb example +``` + +Set a breakpoint in the `my_function` function and run the program: + +``` +(gdb) break my_function +(gdb) run +``` + +Once stopped at the breakpoint, use `next`, `print`, and `continue` to examine the program's state: + +``` +(gdb) next +(gdb) print i +(gdb) continue +``` + +Finally, exit GDB with the `quit` command. + +This was just a brief summary of GDB; you can find more details in the [official GDB manual](https://sourceware.org/gdb/current/onlinedocs/gdb/). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/116-build-systems/100-cmake.md b/src/data/roadmaps/cpp/content/116-build-systems/100-cmake.md index 8e4ba20f7..ac933a90b 100644 --- a/src/data/roadmaps/cpp/content/116-build-systems/100-cmake.md +++ b/src/data/roadmaps/cpp/content/116-build-systems/100-cmake.md @@ -1 +1,59 @@ -# Cmake \ No newline at end of file +# CMake + +CMake is a powerful cross-platform build system that generates build files, Makefiles, or workspaces for various platforms and compilers. Unlike the others build systems, CMake does not actually build the project, it only generates the files needed by build tools. CMake is widely used, particularly in C++ projects, for its ease of use and flexibility. + +### CMakeLists.txt + +CMake uses a file called `CMakeLists.txt` to define settings, source files, libraries, and other configurations. A typical `CMakeLists.txt` for a simple project would look like: + +```cmake +cmake_minimum_required(VERSION 3.0) + +project(MyProject) + +set(SRC_DIR "${CMAKE_CURRENT_LIST_DIR}/src") +set(SOURCES "${SRC_DIR}/main.cpp" "${SRC_DIR}/file1.cpp" "${SRC_DIR}/file2.cpp") + +add_executable(${PROJECT_NAME} ${SOURCES}) + +target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/include") + +set_target_properties(${PROJECT_NAME} PROPERTIES + CXX_STANDARD 14 + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS OFF +) +``` + +### Building with CMake + +Here is an example of a simple build process using CMake: + +1. Create a new directory for the build. + +```sh +mkdir build +cd build +``` + +2. Generate build files using CMake. + +```sh +cmake .. +``` + +In this example, `..` indicates the parent directory where `CMakeLists.txt` is located. The build files will be generated in the `build` directory. + +3. Build the project using the generated build files. + +```sh +make +``` + +Or, on Windows with Visual Studio, you may use: + +```sh +msbuild MyProject.sln +``` + +CMake makes it easy to manage large projects, define custom build configurations, and work with many different compilers and operating systems. Making it a widely chosen tool for managing build systems in C++ projects. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/116-build-systems/101-makefile.md b/src/data/roadmaps/cpp/content/116-build-systems/101-makefile.md index 5692993c4..8373c7bb8 100644 --- a/src/data/roadmaps/cpp/content/116-build-systems/101-makefile.md +++ b/src/data/roadmaps/cpp/content/116-build-systems/101-makefile.md @@ -1 +1,55 @@ -# Makefile \ No newline at end of file +# Makefile + +A Makefile is a configuration file used by the `make` utility to automate the process of compiling and linking code in a C++ project. It consists of a set of rules and dependencies that help in building the target executable or library from source code files. + +Makefiles help developers save time, reduce errors, and ensure consistency in the build process. They achieve this by specifying the dependencies between different source files, and providing commands that generate output files (such as object files and executables) from input files (such as source code and headers). + +### Structure of a Makefile + +A typical Makefile has the following structure: + +1. **Variables**: Define variables to store commonly used values, such as compiler flags, directories, or target names. +2. **Rules**: Define how to generate output files from input files using a set of commands. Each rule has a *target*, a set of *prerequisites*, and a *recipe*. +3. **Phony targets**: Targets that do not represent actual files in the project but serve as a way to group related rules and invoke them using a single command. + +### Example + +Consider a basic C++ project with the following directory structure: + +``` +project/ +|-- include/ +| |-- header.h +|-- src/ +| |-- main.cpp +|-- Makefile +``` + +A simple Makefile for this project could be as follows: + +```make +# Variables +CXX = g++ +CXXFLAGS = -Wall -Iinclude +SRC = src/main.cpp +OBJ = main.o +EXE = my_program + +# Rules +$(EXE): $(OBJ) + $(CXX) $(CXXFLAGS) -o $(EXE) $(OBJ) + +$(OBJ): $(SRC) + $(CXX) $(CXXFLAGS) -c $(SRC) + +# Phony targets +.PHONY: clean +clean: + rm -f $(OBJ) $(EXE) +``` + +With this Makefile, you can simply run `make` in the terminal to build the project, and `make clean` to remove the output files. The Makefile specifies the dependencies between the source code, object files, and the final executable, as well as the commands to compile and link them. + +### Summary + +Makefiles provide a powerful way to automate building C++ projects using the `make` utility. They describe the dependencies and commands required to generate output files from source code, saving time and ensuring consistency in the build process. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/116-build-systems/102-ninja.md b/src/data/roadmaps/cpp/content/116-build-systems/102-ninja.md index 711614553..3d88e2a21 100644 --- a/src/data/roadmaps/cpp/content/116-build-systems/102-ninja.md +++ b/src/data/roadmaps/cpp/content/116-build-systems/102-ninja.md @@ -1 +1,34 @@ -# Ninja \ No newline at end of file +# Ninja + +Ninja is a small build system with a focus on speed. It is designed to handle large projects by generating build files that implement the minimal amount of work necessary to build the code. This results in faster build times, especially for large codebases. Ninja is often used in conjunction with other build systems like CMake, which can generate Ninja build files for you. + +Ninja build files are typically named `build.ninja` and contain rules, build statements, and variable declarations. Here's a simple example of a Ninja build file for a C++ project: + +```ninja +# Variable declarations +cxx = g++ +cflags = -Wall -Wextra -std=c++17 + +# Rule for compiling the C++ files +rule cxx_compile + command = $cxx $cflags -c $in -o $out + +# Build statements for the source files +build main.o: cxx_compile main.cpp +build foo.o: cxx_compile foo.cpp + +# Rule for linking the object files +rule link + command = $cxx $in -o $out + +# Build statement for the final executable +build my_program: link main.o foo.o +``` + +To build the project using this `build.ninja` file, simply run `ninja` in the terminal: + +```bash +$ ninja +``` + +This will build the `my_program` executable by first compiling the `main.cpp` and `foo.cpp` files into object files, and then linking them together. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/117-package-managers/100-vcpkg.md b/src/data/roadmaps/cpp/content/117-package-managers/100-vcpkg.md index cb2ea6feb..a1db619b9 100644 --- a/src/data/roadmaps/cpp/content/117-package-managers/100-vcpkg.md +++ b/src/data/roadmaps/cpp/content/117-package-managers/100-vcpkg.md @@ -1 +1,65 @@ -# Vcpkg \ No newline at end of file +# vcpkg + +`vcpkg` is a cross-platform, open-source package manager for C and C++ libraries. Developed by Microsoft, it simplifies the process of acquiring and building open-source libraries for your projects. `vcpkg` supports various platforms including Windows, Linux, and macOS, enabling you to easily manage and integrate external libraries into your projects. + +### Installation + +To install `vcpkg`, follow these steps: + +1. Clone the repository: + + ``` + git clone https://github.com/Microsoft/vcpkg.git + ``` + +2. Change to the `vcpkg` directory and run the bootstrap script: + + - On Windows: + + ``` + .\bootstrap-vcpkg.bat + ``` + + - On Linux/macOS: + + ``` + ./bootstrap-vcpkg.sh + ``` + +3. (Optional) Add the `vcpkg` executable to your `PATH` environment variable for easy access. + +### Basic usage + +Here are some basic examples of using `vcpkg`: + +- Search for a package: + + ``` + vcpkg search + ``` + +- Install a package: + + ``` + vcpkg install + ``` + +- Remove a package: + + ``` + vcpkg remove + ``` + +- List installed packages: + + ``` + vcpkg list + ``` + +- Integrate `vcpkg` with Visual Studio (Windows only): + + ``` + vcpkg integrate install + ``` + +For additional documentation and advanced usage, you can refer to the [official GitHub repository](https://github.com/microsoft/vcpkg). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/117-package-managers/101-spack.md b/src/data/roadmaps/cpp/content/117-package-managers/101-spack.md index dd2422ddd..d712418ff 100644 --- a/src/data/roadmaps/cpp/content/117-package-managers/101-spack.md +++ b/src/data/roadmaps/cpp/content/117-package-managers/101-spack.md @@ -1 +1,58 @@ -# Spack \ No newline at end of file +# Spack + +[Spack](https://spack.io/) is a flexible package manager designed to support multiple versions, configurations, platforms, and compilers. It is particularly useful in High Performance Computing (HPC) environments and for those who require fine control over their software stack. Spack is a popular choice in scientific computing due to its support for various platforms such as Linux, macOS, and many supercomputers. It is designed to automatically search for and install dependencies, making it easy to build complex software. + +### Key Features + +- **Multi-Version Support**: Spack allows for the installation of multiple versions of packages, enabling users to work with different configurations depending on their needs. +- **Compiler Support**: Spack supports multiple compilers, including GCC, Clang, Intel, PGI, and others, allowing users to choose the best toolchain for their application. +- **Platform Support**: Spack can run on Linux, macOS, and various supercomputers, and it can even target multiple architectures within a single package. +- **Dependencies**: Spack takes care of dependencies, providing automatic installation and management of required packages. + +### Basic Usage + +1. To install Spack, clone its Git repository and set up your environment: + + ```bash + git clone https://github.com/spack/spack.git + cd spack + . share/spack/setup-env.sh + ``` + +2. Install a package using Spack: + + ```bash + spack install + ``` + + For example, to install `hdf5`: + + ```bash + spack install hdf5 + ``` + +3. Load a package in your environment: + + ```bash + spack load + ``` + + For example, to load `hdf5`: + + ```bash + spack load hdf5 + ``` + +4. List installed packages: + + ```bash + spack find + ``` + +5. Uninstall a package: + + ```bash + spack uninstall + ``` + +For more advanced usage, like installing specific versions or using different compilers, consult the [Spack documentation](https://spack.readthedocs.io/). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/117-package-managers/102-conan.md b/src/data/roadmaps/cpp/content/117-package-managers/102-conan.md index 3c3c6a4fa..3b85cabb9 100644 --- a/src/data/roadmaps/cpp/content/117-package-managers/102-conan.md +++ b/src/data/roadmaps/cpp/content/117-package-managers/102-conan.md @@ -1 +1,79 @@ -# Conan \ No newline at end of file +# Conan + +[Conan](https://conan.io/) is a popular package manager for C and C++ languages and is designed to be cross-platform, extensible, and easy to use. It allows developers to declare, manage, and fetch dependencies while automating the build process. Conan supports various build systems, such as CMake, Visual Studio, MSBuild, and more. + +### Installation + +To install Conan, you can use pip, the Python package manager: + +```bash +pip install conan +``` + +### Basic Usage + +1. Create a `conanfile.txt` file in your project root directory, specifying dependencies you need for your project: + +```ini +[requires] +boost/1.75.0 + +[generators] +cmake +``` + +2. Run the `conan install` command to fetch and build required dependencies: + +```bash +mkdir build && cd build +conan install .. +``` + +3. Now build your project using your build system, for example CMake: + +```bash +cmake .. -DCMAKE_BUILD_TYPE=Release +cmake --build . +``` + +### Creating Packages + +To create a package in Conan, you need to write a `conanfile.py` file with package information and build instructions. + +Here's an example: + +```python +from conans import ConanFile, CMake + +class MyLibraryConan(ConanFile): + name = "MyLibrary" + version = "0.1" + license = "MIT" + url = "https://github.com/username/mylibrary" + description = "A simple example library" + settings = "os", "compiler", "build_type", "arch" + generators = "cmake" + + def build(self): + cmake = CMake(self) + cmake.configure(source_folder="src") + cmake.build() + + def package(self): + self.copy("*.hpp", dst="include", src="src/include") + self.copy("*.lib", dst="lib", keep_path=False) + self.copy("*.dll", dst="bin", keep_path=False) + self.copy("*.so", dst="lib", keep_path=False) + self.copy("*.a", dst="lib", keep_path=False) + + def package_info(self): + self.cpp_info.libs = ["MyLibrary"] +``` + +With that setup, you can create a package by running: + +```bash +conan create . username/channel +``` + +This will compile the package and store it in your Conan cache. You can now use this package as a dependency in other projects. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/117-package-managers/103-nuget.md b/src/data/roadmaps/cpp/content/117-package-managers/103-nuget.md index a13b8ce9b..74c6a300c 100644 --- a/src/data/roadmaps/cpp/content/117-package-managers/103-nuget.md +++ b/src/data/roadmaps/cpp/content/117-package-managers/103-nuget.md @@ -1 +1,45 @@ -# Nuget \ No newline at end of file +# NuGet + +[NuGet](https://www.nuget.org/) is a Microsoft-supported package manager for the .NET framework, mainly used in C# and other .NET languages, but also supports C++ projects with `PackageReference`. It allows you to easily add, update, and manage dependencies in your projects. + +#### Installation + +You can use NuGet either as a command-line tool or integrated in your preferred IDE like Visual Studio or Visual Studio Code. If you're using Visual Studio, it comes pre-installed. For other editors, you may need to download the command-line tool `nuget.exe`. + +#### Usage + +You can use NuGet to manage your C++ dependencies using the PackageReference format in vcxproj files: + +1. Tools > NuGet Package Manager > Manage NuGet Packages for Solution… +2. Package source should be set to "nuget.org" +3. Select the Projects tab +4. Use the search box to find packages + +For example, to install a package called "PackageName" for all configurations: + +```xml + + + + + ... + +``` + +#### NuGet Command-Line + +You can also use the command-line tool `nuget.exe` for more advanced scenarios or for specific needs. + +Here's an example of installing a package using the command line: + +```bash +nuget install PackageName +``` + +And updating a package: + +```bash +nuget update PackageName +``` + +For more information and detailed examples on using NuGet in your projects, please refer to the [official documentation](https://docs.microsoft.com/en-us/nuget/guides/native-packages). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/117-package-managers/index.md b/src/data/roadmaps/cpp/content/117-package-managers/index.md index 72768f6f4..6f719fcf0 100644 --- a/src/data/roadmaps/cpp/content/117-package-managers/index.md +++ b/src/data/roadmaps/cpp/content/117-package-managers/index.md @@ -1 +1,50 @@ -# Package managers \ No newline at end of file +# Package Managers + +Package managers are tools that automate the process of installing, upgrading, and managing software (libraries, frameworks, and other dependencies) for a programming language, such as C++. + +Some popular package managers used in the C++ ecosystem include: + +1. **Conan** +2. **vcpkg** +3. **C++ Archive Network (cppan)** + +### Conan + +[Conan](https://conan.io/) is an open-source, decentralized, cross-platform package manager for C and C++ developers. It simplifies managing dependencies and reusing code, which benefits multi-platform development projects. + +For example, installing a library using Conan: + +```sh +conan install poco/1.9.4@ +``` + +### vcpkg + +[vcpkg](https://github.com/microsoft/vcpkg) is a cross-platform package manager created by Microsoft. It is an open-source library management system for C++ developers to build and manage their projects. + +For example, installing a package using vcpkg: + +```sh +./vcpkg install boost:x64-windows +``` + +### C++ Archive Network (cppan) + +[cppan](https://cppan.org/) is a package manager and software repository for C++ developers, simplifying the process of managing and distributing C++ libraries and tools. It's now part of [build2](https://build2.org/), a build toolchain that provides a package manager. + +An example of a `cppan.yml` file: + +```yaml +# +# cppan.yml +# + +project: + api_version: 1 + + depend: + - pvt.cppan.demo.sqlite3 + - pvt.cppan.demo.xz_utils.lzma +``` + +With these package managers, you can streamline your development process and easily manage dependencies in your C++ projects. In addition, you can easily reuse the code in your projects to improve code quality and accelerate development. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/118-working-with-libs/100-inclusion.md b/src/data/roadmaps/cpp/content/118-working-with-libs/100-inclusion.md index b328944ab..c8bb10a42 100644 --- a/src/data/roadmaps/cpp/content/118-working-with-libs/100-inclusion.md +++ b/src/data/roadmaps/cpp/content/118-working-with-libs/100-inclusion.md @@ -1 +1,37 @@ -# Inclusion \ No newline at end of file +# Inclusion in C++ + +In C++ programming, inclusion refers to incorporating external libraries, header files, or other code files into your program. This process allows developers to access pre-built functions, classes, and variable declarations that can be used in their own code. There are two types of inclusion in C++: + +1. Header Inclusion +2. Source Inclusion + +#### Header Inclusion + +Header inclusion involves including header files using the preprocessor directive `#include`. Header files are typically used to provide function prototypes, class declarations, and constant definitions that can be shared across multiple source files. There are two ways to include header files in your program: + +- Angle brackets `<>`: Used for including standard library headers, like `iostream`, `vector`, or `algorithm`. + +Example: +```cpp +#include +#include +``` + +- Double quotes `""`: Used for including user-defined headers or headers provided by third-party libraries. + +Example: +```cpp +#include "myHeader.h" +#include "thirdPartyLibrary.h" +``` + +#### Source Inclusion + +Source inclusion refers to including the content of a source file directly in another source file. This approach is generally not recommended as it can lead to multiple definitions and increased compile times but it can occasionally be useful for certain tasks (e.g., templates or simple small programs). To include a source file, you can use the `#include` directive with double quotes, just like with header files: + +Example: +```cpp +#include "mySourceFile.cpp" +``` + +Remember, using source inclusion for large projects or in situations where it's not necessary can lead to unexpected issues and should be avoided. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/118-working-with-libs/101-licensing.md b/src/data/roadmaps/cpp/content/118-working-with-libs/101-licensing.md index 6ffdbdd5f..6869e0b15 100644 --- a/src/data/roadmaps/cpp/content/118-working-with-libs/101-licensing.md +++ b/src/data/roadmaps/cpp/content/118-working-with-libs/101-licensing.md @@ -1 +1,39 @@ -# Licensing \ No newline at end of file +# Licensing in C++ + +Licensing is a crucial aspect of working with libraries in C++ because it determines the rights and limitations on how you can use, modify, and distribute a given library. There are various types of licenses applied to open-source libraries. Below is a brief overview of three common licenses: + +#### 1. MIT License + +The MIT License is a permissive license that allows users to do whatever they want with the software code. They only need to include the original copyright, license notice, and a disclaimer of warranty in their copies. + +Example: Including the MIT License into your project can be done by simply adding the license file and a notice at the top of your source code files like: + +```cpp +/* Copyright (C) [year] [author] + * SPDX-License-Identifier: MIT + */ +``` + +#### 2. GNU General Public License (GPL) +The GPL is a copyleft license that grants users the rights to use, study, share, and modify the software code. However, any changes made to the code or any software that uses GPL licensed code must also be distributed under the GPL license. + +Example: To include a GPL license in your project, include a `COPYING` file with the full text of the license and place a notice in your source code files like: + +```cpp +/* Copyright (C) [year] [author] + * SPDX-License-Identifier: GPL-3.0-or-later + */ +``` + +#### 3. Apache License 2.0 +The Apache License is a permissive license similar to the MIT license and allows users to do virtually anything with the software code. The primary difference is that it requires that any changes to the code are documented, and it provides specific terms for patent protection. + +Example: To include the Apache License in your project, add a `LICENSE` file with the full text of the license. Add a notice to your source code files like: + +```cpp +/* Copyright (C) [year] [author] + * SPDX-License-Identifier: Apache-2.0 + */ +``` + +Please note that these are brief summaries of the licenses, and there are many other licenses available for use in software projects. When using third-party libraries, it is crucial to understand and adhere to the terms of their respective licenses to avoid legal complications. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/frameworks/101-qt.md b/src/data/roadmaps/cpp/content/frameworks/101-qt.md index 21990d50c..9d5d62479 100644 --- a/src/data/roadmaps/cpp/content/frameworks/101-qt.md +++ b/src/data/roadmaps/cpp/content/frameworks/101-qt.md @@ -1 +1,37 @@ -# Qt \ No newline at end of file +# Qt Framework + +Qt is an open-source, cross-platform framework for creating high-performance applications with interactive user interfaces. It is mainly used for developing GUI applications but can also be used for creating non-GUI applications like console tools and servers. + +Qt provides a wide range of C++ libraries and seamless integration with popular IDEs, making it easier for developers to create feature-rich applications. It offers a comprehensive development environment, including tools for designing, coding, debugging, and profiling applications. + +### Key Features + +- **Cross-platform**: Qt can create applications that run on different platforms (e.g., Windows, macOS, Linux, Android, iOS) without any platform-specific code. +- **Modular Libraries**: Qt consists of several modular libraries, including QtCore (core non-GUI functionality), QtGui (GUI-related classes), QtWidgets (GUI widgets), and QtNetwork (networking support). +- **Signals and Slots**: Qt provides a unique mechanism to handle events called "signals and slots", which allows safe and flexible inter-object communication. +- **OpenGL Integration**: Qt supports rendering 2D and 3D graphics using OpenGL, making it suitable for game development and other graphical applications. + +### Code Example + +Here's a simple example of a "Hello, World!" application using Qt: + +```cpp +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QLabel label("Hello, World!"); + label.show(); + + return app.exec(); +} +``` + +In this example, we include the necessary header files, create QApplication and QLabel objects, display the label with a "Hello, World!" message, and execute the application. + +To compile and run this example, you need to install the Qt library and configure your development environment to use it. + +For more information and tutorials about Qt, you can refer to the [official Qt documentation](https://doc.qt.io/qt-5/index.html). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/frameworks/103-orbit-profiler.md b/src/data/roadmaps/cpp/content/frameworks/103-orbit-profiler.md index 077a3ce2a..61c5d19ce 100644 --- a/src/data/roadmaps/cpp/content/frameworks/103-orbit-profiler.md +++ b/src/data/roadmaps/cpp/content/frameworks/103-orbit-profiler.md @@ -1 +1,69 @@ -# Orbit profiler \ No newline at end of file +# Orbit Profiler + +Orbit Profiler is a performance profiler for C++ applications. It is designed to provide developers with real-time feedback on their application's performance and help them identify performance bottlenecks. It supports both Windows and Linux platforms, profiling both local and remote processes. + +**Major features of Orbit Profiler:** + +- Sampling-based profiling +- Instrumentation-based profiling +- Callstacks collection +- Frame-based measurements using scopes macros + +### Usage + +1. **Include OrbitProfiler.h**: First, you need to include the `OrbitProfiler.h` header file in your project: + + ```cpp + #include "OrbitProfiler.h" + ``` + +2. **Starting and Stopping the profiler**: Use `ORBET_START` and `ORBIT_STOP` to start and stop the profiler. + + ```cpp + ORBIT_START(); + // Your application code here + ORBIT_STOP(); + ``` + +3. **Instrumenting scopes**: Use the `ORBET_SCOPE` macro to annotate the scope of the function you want to measure: + + ```cpp + void ExampleFunction() { + ORBIT_SCOPE("Example Function"); + // Function content here + } + ``` + +4. **Visualizing the captured data**: Orbit Profiler provides a **Session View** that displays the captured data and allows you to navigate through the timeline, analyze data, and identify performance bottlenecks. + +### Example + +For demonstration purposes, consider the following example of a simple C++ application: + +```cpp +#include "OrbitProfiler.h" + +void FunctionA() { + ORBIT_SCOPE("Function A"); + // Function A code here +} + +void FunctionB() { + ORBIT_SCOPE("Function B"); + // Function B code here +} + +int main() { + ORBIT_START(); + + FunctionA(); + FunctionB(); + + ORBIT_STOP(); + return 0; +} +``` + +By using Orbit Profiler, we are able to pinpoint performance issues in FunctionA and FunctionB and optimize our application accordingly. + +For more information, refer to the [official Orbit Profiler GitHub repository](https://github.com/google/orbit). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/libraries/100-boost.md b/src/data/roadmaps/cpp/content/libraries/100-boost.md index a8fd35294..471876219 100644 --- a/src/data/roadmaps/cpp/content/libraries/100-boost.md +++ b/src/data/roadmaps/cpp/content/libraries/100-boost.md @@ -1 +1,45 @@ -# Boost \ No newline at end of file +# Boost C++ Libraries + +Boost is a collection of high-quality and widely-used C++ libraries that are designed to help developers write efficient and portable code. They are modular and can be included in your projects as needed. Boost libraries provide various functionalities, including support for parallelism, multithreading, memory management, string manipulation, and advanced data structures. + +## Notable Components + +Here's a list of some popular Boost libraries: + +- **Boost.Asio**: Provides network and low-level I/O services. +- **Boost.Bimap**: A bidirectional map data structure. +- **Boost.Filesystem**: Offers portable file system operations. +- **Boost.Graph**: Implements various graph algorithms and data structures. +- **Boost.Multithreading**: Offers multithreading, synchronization, and thread management tools. + +## Usage + +1. First, download and install the Boost libraries according to the [documentation](https://www.boost.org/doc/libs/1_76_0/more/getting_started/index.html). +2. After installation, include necessary headers in your C++ code and start using Boost facilities. + +Here's an example using `boost::filesystem` (*NOTE: Boost.Filesystem is now part of the C++17 standard library*): + +```cpp +#include +#include + +int main() { + boost::filesystem::path path("directory_path"); + + if (boost::filesystem::exists(path)) { + std::cout << "Path: " << path << " exists!" << std::endl; + + if (boost::filesystem::is_directory(path)) { + std::cout << "Path: " << path << " is a directory." << std::endl; + } else if (boost::filesystem::is_regular_file(path)) { + std::cout << "Path: " << path << " is a regular file." << std::endl; + } + } else { + std::cout << "Path: " << path << " does not exist!" << std::endl; + } + + return 0; +} +``` + +For a more detailed guide, refer to the [official Boost documentation](https://www.boost.org/doc/libs/). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/libraries/101-open-cv.md b/src/data/roadmaps/cpp/content/libraries/101-open-cv.md index f9cd1f073..f763ef007 100644 --- a/src/data/roadmaps/cpp/content/libraries/101-open-cv.md +++ b/src/data/roadmaps/cpp/content/libraries/101-open-cv.md @@ -1 +1,57 @@ -# Open cv \ No newline at end of file +# OpenCV + +**OpenCV (Open Source Computer Vision Library)** is an open-source computer vision and machine learning software library. It was built to provide a common infrastructure for computer vision applications and to accelerate the use of machine perception in commercial products. OpenCV contains over 2,500 optimized algorithms for real-time computer vision and is actively used by a large community of programmers, researchers, and industries worldwide. + +The library has interfaces for C++, Python, Java, and MATLAB/Octave, and is widely used in various computer vision fields, such as: + +- 2D and 3D image processing +- Facial recognition and face detection +- Object detection and recognition +- Machine learning + +Here's a simple example using OpenCV in C++ to read and display an image: + +**Prerequisite**: Install OpenCV for C++ on your system (e.g., by following the [official installation guide](https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html)). + +```cpp +#include +#include +#include + +int main(int argc, char** argv) { + if(argc != 2) { + std::cout << "Usage: display_image ImageToLoadAndDisplay" << std::endl; + return -1; + } + + cv::Mat image; + image = cv::imread(argv[1], cv::IMREAD_COLOR); + + if(!image.data) { + std::cout << "Could not open or find the image" << std::endl; + return -1; + } + + cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE); + cv::imshow("Display window", image); + cv::waitKey(0); + + return 0; +} +``` + +This example reads an image from the given input path (`argv[1]`) and displays it in a window. The `cv::imread()` function is used to read the image, and the `cv::imshow()` function displays it in the created window. + +Remember to compile the code, linking the necessary libraries: + +``` +g++ -o display_image display_image.cpp `pkg-config --cflags --libs opencv4` +``` + +And run the executable with an image path as an argument: + +``` +./display_image path/to/image.jpg +``` + +For more advanced examples and detailed documentation on how to use OpenCV, please visit the [official OpenCV documentation](https://docs.opencv.org/master/). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/libraries/102-poco.md b/src/data/roadmaps/cpp/content/libraries/102-poco.md index 67639991d..895864691 100644 --- a/src/data/roadmaps/cpp/content/libraries/102-poco.md +++ b/src/data/roadmaps/cpp/content/libraries/102-poco.md @@ -1 +1,71 @@ -# Poco \ No newline at end of file +# Poco + +Poco (also known as POCO C++ Libraries) is a collection of open-source class libraries, which simplifies the creation of network-centric, portable, and maintainable software in C++. + +### Overview + +Poco library provides functionality for various areas, such as: + +- Networking: HTTP, FTP, SMTP, POP3, and other internet protocols +- File handling: FileSystem, Path, File, and Directory classes +- XML processing: XML parsing and DOM manipulation +- Logging: Loggers, levels, channels, patterns, etc. +- Data manipulation: Stream, ByteBuffer, Buffer, etc. +- Multithreading and synchronization: Threads, Mutex, Event, and Condition + +### Code Example + +Here's an example demonstrating an HTTP client using the Poco library: + +```cpp +#include +#include +#include +#include +#include +#include +#include + +using namespace Poco::Net; +using namespace Poco; +using namespace std; + +int main() +{ + try + { + // Prepare the request + URI uri("http://example.com"); + HTTPClientSession session(uri.getHost(), uri.getPort()); + + HTTPRequest request(HTTPRequest::HTTP_GET, uri.getPath(), HTTPMessage::HTTP_1_1); + request.setContentType("application/json"); + + session.sendRequest(request); + + // Process the response + HTTPResponse response; + istream& responseStream = session.receiveResponse(response); + if (response.getStatus() == HTTPResponse::HTTP_OK) + { + // Successful + StreamCopier::copyToString(responseStream, responseBody); + cout << "Response: " << responseBody << endl; + } + else + { + // Error + cout << "Error: " << response.getStatus() << " " << response.getReason() << endl; + } + } + catch(const Exception& e) + { + cerr << "Error: " << e.displayText() << endl; + return -1; + } + + return 0; +} +``` + +In the above example, Poco is used to send an HTTP GET request and process the response. It manages tasks like connecting to the server, handling exceptions, and managing HTTP headers. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/libraries/105-tensorflow.md b/src/data/roadmaps/cpp/content/libraries/105-tensorflow.md index 9e0e0b593..8fd4cef8f 100644 --- a/src/data/roadmaps/cpp/content/libraries/105-tensorflow.md +++ b/src/data/roadmaps/cpp/content/libraries/105-tensorflow.md @@ -1 +1,53 @@ -# Tensorflow \ No newline at end of file +# TensorFlow + +TensorFlow is an open-source machine learning library developed by researchers and engineers from the Google Brain team. It is designed for building, training, and deploying deep learning models. TensorFlow provides a set of tools for ML, deep learning, and numerical computation using data flow graphs. TensorFlow can process computations on GPUs and TPUs, which speed up training time and ensures efficient model deployment. + +## Installation + +You can install TensorFlow using the Python package manager pip: + +```bash +pip install tensorflow +``` + +## Basic usage + +Here's a simple example of how to create and train a neural network with TensorFlow: + +```python +import tensorflow as tf +from tensorflow import keras + +# Load dataset +mnist = keras.datasets.mnist +(train_images, train_labels), (test_images, test_labels) = mnist.load_data() + +# Preprocess data +train_images = train_images / 255.0 +test_images = test_images / 255.0 + +# Define model +model = keras.Sequential([ + keras.layers.Flatten(input_shape=(28, 28)), + keras.layers.Dense(128, activation='relu'), + keras.layers.Dense(10, activation='softmax') +]) + +# Compile model +model.compile(optimizer='adam', + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + +# Train model +model.fit(train_images, train_labels, epochs=5) + +# Evaluate model +test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2) +print('\nTest accuracy:', test_acc) +``` + +This code loads the MNIST dataset, preprocesses the data, creates a simple neural network, compiles it, trains it, and evaluates its performance on the test set. + +For more advanced usage, TensorFlow offers several APIs like `tf.data`, `tf.keras`, and `tf.estimator` that enable flexible and efficient data input pipelines, composing and training complex neural network architectures, and managing large-scale distributed training. + +You can visit TensorFlow's official website (https://www.tensorflow.org/) and their GitHub repository (https://github.com/tensorflow/tensorflow) for more information, tutorials, and resources. \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/libraries/107-spdlog.md b/src/data/roadmaps/cpp/content/libraries/107-spdlog.md index 6e72c4268..d979a5e08 100644 --- a/src/data/roadmaps/cpp/content/libraries/107-spdlog.md +++ b/src/data/roadmaps/cpp/content/libraries/107-spdlog.md @@ -1 +1,59 @@ -# Spdlog \ No newline at end of file +# Spdlog + +`spdlog` is a fast, header-only, C++ logging library. It provides a simple and efficient way to add diagnostic logging to your C++ application. + +### Features: +- Header-only, no need to build or link a library +- Highly configurable, including support for custom log sinks (e.g. writing to a file or a database) +- Asynchronous and synchronous logging modes +- Preprocessor-based format string checks to catch bugs at compile-time +- Easy to extend with custom formatters, sinks, and levels + +### Usage example: + +Include the `spdlog` header, create a logger object, and use it to log messages: + +```cpp +#include "spdlog/spdlog.h" + +int main() { + // Create a logger with the name "example_logger" + auto logger = spdlog::stdout_color_mt("example_logger"); + + // Log messages with various severity levels + logger->info("Welcome to spdlog!"); + logger->warn("Warning message"); + logger->error("Error message"); + + return 0; +} +``` + +### Custom sink example: + +Here's an example of creating a logger with a custom sink that writes to a text file: + +```cpp +#include "spdlog/spdlog.h" +#include "spdlog/sinks/basic_file_sink.h" + +int main() { + // Create a file sink to write logs to "logs.txt" + auto file_sink = std::make_shared("logs.txt"); + + // Create a logger with the file sink and the name "example_logger" + auto logger = std::make_shared("example_logger", file_sink); + + // Register the logger + spdlog::register_logger(logger); + + // Log messages + logger->info("Welcome to spdlog!"); + logger->warn("Warning message"); + logger->error("Error message"); + + return 0; +} +``` + +For more examples and detailed documentation, visit the [spdlog GitHub repository](https://github.com/gabime/spdlog). \ No newline at end of file diff --git a/src/data/roadmaps/cpp/content/libraries/109-fmt.md b/src/data/roadmaps/cpp/content/libraries/109-fmt.md index 7f0fe40d8..92b00796e 100644 --- a/src/data/roadmaps/cpp/content/libraries/109-fmt.md +++ b/src/data/roadmaps/cpp/content/libraries/109-fmt.md @@ -1 +1,69 @@ -# Fmt \ No newline at end of file +# fmt + +`fmt` is a modern C++ formatting library that provides an easy and efficient way to format text and print it to various outputs. The library offers a high level of compatibility with C++ standards, making it suitable for various applications and platforms. `fmt` emphasizes simplicity, extensibility, and type safety. + +## Features + +- Supports positional and named arguments for better readability in complex formatting tasks +- Supports format string syntax similar to Python's `str.format()` +- Provides compile-time format string checks for type safety +- Extensive documentation and user-friendly API + +## Example Usage + +Here are some examples of how to use the `fmt` library: + +### Basic Usage + +```cpp +#include + +int main() { + fmt::print("Hello, world!\n"); + return 0; +} +``` + +### Formatting with Positional Arguments + +```cpp +#include + +int main() { + fmt::print("The answer is {}.\n", 42); + fmt::print("{1}, {0}!\n", "world", "Hello"); + return 0; +} +``` + +### Formatting with Named Arguments + +```cpp +#include + +int main() { + fmt::print("Hello, {name}!\n", fmt::arg("name", "world")); + return 0; +} +``` + +### Using Format String Syntax + +```cpp +#include + +int main() { + fmt::print("{:<30}", "left-aligned"); + fmt::print("{:>30}", "right-aligned"); + fmt::print("{:^30}", "center-aligned"); + fmt::print("{:*^30}", "center-aligned"); + + fmt::print("int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); + fmt::print("{:.2f}", 3.1415926); + fmt::print("{:010.2f}", 3.1415926); + + return 0; +} +``` + +For more information, you can refer to the official [fmt documentation](https://fmt.dev/latest/index.html). \ No newline at end of file