diff --git a/lectures/optional_and_variant.md b/lectures/optional_and_variant.md
new file mode 100644
index 0000000..27285fc
--- /dev/null
+++ b/lectures/optional_and_variant.md
@@ -0,0 +1,144 @@
+
+**`std::optional` and `std::variant` in Modern C++**
+--
+
+
+
+
+
+## **Introduction**
+
+When working with modern C++ (C++17 and beyond), we often need tools to handle optional values or represent data that can take one of several types. That’s where `std::optional` and `std::variant` come into play. Today, we’ll explore what these features are, why they’re useful, and how you can leverage them in your projects.
+
+
+## **What is `std::optional`?**
+
+### Why use `std::optional`?
+
+Imagine a function that searches for an item in a container. If the item is found, the function should return it. But what if it isn’t? Before C++17, you might have returned a special value (like `-1` for integers) or used a pointer, potentially introducing ambiguity or risking undefined behavior.
+
+`std::optional` solves this by explicitly representing the absence of a value. It's a type-safe mechanism that avoids the pitfalls of ad-hoc solutions.
+
+### Examples of `std::optional` in action
+
+#### A simple search function
+
+````cpp
+#include
+#include
+#include
+
+std::optional Find(const std::vector& data, int value) {
+ for (int element : data) {
+ if (element == value) {
+ return element; // Return the value if found
+ }
+ }
+ return std::nullopt; // Explicitly indicate "no value"
+}
+
+int main() {
+ std::vector numbers = {1, 2, 3, 4, 5};
+ auto result = Find(numbers, 3);
+
+ if (result) { // Check if a value exists
+ std::cout << "Found: " << *result << '\n';
+ } else {
+ std::cout << "Not found.\n";
+ }
+}
+````
+In this example, `std::optional` clearly communicates that the function may or may not return a value.
+
+#### A factory function
+
+````cpp
+std::optional CreateString(bool should_create) {
+ if (should_create) {
+ return "Hello, World!";
+ }
+ return std::nullopt;
+}
+
+int main() {
+ auto maybe_string = CreateString(true);
+
+ if (maybe_string) {
+ std::cout << *maybe_string << '\n';
+ } else {
+ std::cout << "No string created.\n";
+ }
+}
+````
+---
+
+## **What is `std::variant`?**
+
+### Why use `std::variant`?
+
+`std::variant` is a type-safe union introduced in C++17. It allows a variable to hold one value out of a defined set of types. Think of it as a more flexible alternative to `enum` or `std::any`, but with static type checking.
+
+For instance, if a variable can hold either an integer or a string, you can use `std::variant` instead of rolling your own solution with `void*` or `boost::variant`.
+
+### Examples of `std::variant` in action
+
+#### Basic usage
+
+````cpp
+#include
+#include
+#include
+
+int main() {
+ std::variant value;
+
+ value = 42; // Assign an integer
+ std::cout << "Integer: " << std::get(value) << '\n';
+
+ value = "Hello, std::variant!"; // Assign a string
+ std::cout << "String: " << std::get(value) << '\n';
+}
+````
+#### Pattern matching with `std::visit`
+
+````cpp
+#include
+#include
+#include
+
+int main() {
+ std::variant value = "Hello, Variant!";
+
+ std::visit([](auto&& arg) {
+ using T = std::decay_t;
+ if constexpr (std::is_same_v) {
+ std::cout << "Integer: " << arg << '\n';
+ } else if constexpr (std::is_same_v) {
+ std::cout << "String: " << arg << '\n';
+ }
+ }, value);
+}
+````
+Here, `std::visit` applies a visitor (a callable object) to the value contained in the variant.
+
+---
+
+## **Key differences and common use cases**
+
+| Feature | `std::optional` | `std::variant` |
+|--------------------|------------------------------------------------------|------------------------------------------------|
+| Purpose | Represents optional values (may or may not exist). | Represents one of several types. |
+| Typical Use Case | Returning a value or "nothing" from a function. | Handling inputs or data with multiple types. |
+| Type Safety | Yes. | Yes. |
+| Pattern Matching | Not applicable. | Supported via `std::visit`. |
+
+---
+
+## **Summary**
+
+`std::optional` and `std::variant` are two powerful tools in the C++ toolbox that greatly enhance type safety and code readability.
+
+- Use `std::optional` when a value might be absent.
+- Use `std::variant` when a value can be one of several types.
+
+These features enable us to write cleaner, more expressive code while avoiding common pitfalls. Experiment with them in your projects and see how they can simplify your development workflow!