# optional

***

**1. Default Initialization**

```cpp
std::optional<int> opt; // Initialized to empty (no value)
```

**2. Value Initialization**

```cpp
std::optional<int> opt1 = 10; // Initialized with value 10
```

**3. Copy Initialization**

```cpp
std::optional<int> opt2(opt1); // Copy the value from opt1
```

**4. Move Initialization**

```cpp
std::optional<int> opt3(std::move(opt2)); // Move the value from opt2
```

**5. Assignment**

```cpp
opt = 20; // Assigns the value 20 to opt
```

**6. Copying Value**

```cpp
int val = *opt; // Dereferences to get the value
```

**7. Checking for Value**

```cpp
if (opt) { // Checks if opt has a value
  // Execute code if opt has a value
}
```

**8. Checking for Empty**

```cpp
if (!opt) { // Checks if opt is empty
  // Execute code if opt is empty
}
```

**9. Using std::visit with std::optional**

```cpp
std::visit([](auto&& val) { std::cout << val; }, opt); // Print the value using polymorphic visitor
```

**10. Using Lambda with std::optional**

```cpp
opt.value_or(0); // Returns the value if present, otherwise returns 0
```

**11. Using Function Pointers with std::optional**

```cpp
auto func = [](auto&& val) { std::cout << val; };
std::visit(func, opt); // Print the value using function pointer
```

**12. Using Algorithm with std::optional**

```cpp
std::for_each(std::begin(opt), std::end(opt), [](auto&& val) { std::cout << val; }); // Iterate over the value
```

**13. Using std::copy with std::optional**

```cpp
std::copy(std::begin(opt), std::end(opt), std::back_inserter(vec)); // Copy the value to a vector
```

**14. Using std::transform with std::optional**

```cpp
std::transform(std::begin(opt), std::end(opt), std::back_inserter(vec), [](auto&& val) { return std::to_string(val); }); // Transform the value to a string vector
```

**15. Using std::find with std::optional**

```cpp
auto it = std::find(std::begin(opt), std::end(opt), 10); // Find the first instance of 10 in opt
```

**16. Using std::count with std::optional**

```cpp
std::count(std::begin(opt), std::end(opt), 10); // Count the number of instances of 10 in opt
```

**17. Using std::accumulate with std::optional**

```cpp
std::accumulate(std::begin(opt), std::end(opt), 0); // Sum the values in opt
```

**18. Using std::minmax with std::optional**

```cpp
std::pair<int, int> result = std::minmax(opt1, opt2); // Find the minimum and maximum values from opt1 and opt2
```

**19. Using std::max\_element with std::optional**

```cpp
auto it = std::max_element(std::begin(opt), std::end(opt)); // Find the iterator to the maximum value in opt
```

**20. Using std::min\_element with std::optional**

```cpp
auto it = std::min_element(std::begin(opt), std::end(opt)); // Find the iterator to the minimum value in opt
```

**21. Using std::sort with std::optional**

```cpp
std::sort(std::begin(opt), std::end(opt)); // Sort the values in opt
```

**22. Using std::reverse with std::optional**

```cpp
std::reverse(std::begin(opt), std::end(opt)); // Reverse the values in opt
```

**23. Using std::rotate with std::optional**

```cpp
std::rotate(std::begin(opt), std::begin(opt) + 1, std::end(opt)); // Rotate the values in opt by 1
```

**24. Using std::partition with std::optional**

```cpp
auto it = std::partition(std::begin(opt), std::end(opt), [](auto&& val) { return val % 2 == 0; }); // Partition the values in opt based on even or odd
```

**25. Using std::stable\_partition with std::optional**

```cpp
auto it = std::stable_partition(std::begin(opt), std::end(opt), [](auto&& val) { return val % 2 == 0; }); // Partition the values in opt based on even or odd, preserving order
```

**26. Using std::remove with std::optional**

```cpp
auto it = std::remove(std::begin(opt), std::end(opt), 10); // Remove all instances of 10 from opt
```

**27. Using std::remove\_if with std::optional**

```cpp
auto it = std::remove_if(std::begin(opt), std::end(opt), [](auto&& val) { return val % 2 == 0; }); // Remove all even values from opt
```

**28. Using std::unique with std::optional**

```cpp
auto it = std::unique(std::begin(opt), std::end(opt)); // Remove duplicates from opt
```

**29. Using std::merge with std::optional**

```cpp
std::optional<int> opt4 = 15;
std::optional<int> opt5 = 20;
std::merge(std::begin(opt1), std::end(opt1), std::begin(opt4), std::end(opt4), std::back_inserter(vec)); // Merge opt1 and opt4 into vec
```

**30. Using std::set\_union with std::optional**

```cpp
std::set_union(std::begin(opt1), std::end(opt1), std::begin(opt4), std::end(opt4), std::back_inserter(vec)); // Union of opt1 and opt4 into vec
```

**31. Using std::set\_intersection with std::optional**

```cpp
std::set_intersection(std::begin(opt1), std::end(opt1), std::begin(opt4), std::end(opt4), std::back_inserter(vec)); // Intersection of opt1 and opt4 into vec
```

**32. Using std::set\_difference with std::optional**

```cpp
std::set_difference(std::begin(opt1), std::end(opt1), std::begin(opt4), std::end(opt4), std::back_inserter(vec)); // Difference of opt1 and opt4 into vec
```

**33. Using std::set\_symmetric\_difference with std::optional**

```cpp
std::set_symmetric_difference(std::begin(opt1), std::end(opt1), std::begin(opt4), std::end(opt4), std::back_inserter(vec)); // Symmetric difference of opt1 and opt4 into vec
```

**34. Using std::map with std::optional**

```cpp
std::map<int, std::optional<int>> map;
map.insert(std::make_pair(1, 10)); // Insert a key-value pair into the map
```

**35. Using std::unordered\_map with std::optional**

```cpp
std::unordered_map<int, std::optional<int>> umap;
umap.insert(std::make_pair(1, 10)); // Insert a key-value pair into the unordered map
```

**36. Using std::multimap with std::optional**

```cpp
std::multimap<int, std::optional<int>> mmap;
mmap.insert(std::make_pair(1, 10)); // Insert a key-value pair into the multimap
```

**37. Using std::unordered\_multimap with std::optional**

```cpp
std::unordered_multimap<int, std::optional<int>> ummap;
ummap.insert(std::make_pair(1, 10)); // Insert a key-value pair into the unordered multimap
```

**38. Using std::set with std::optional**

```cpp
std::set<std::optional<int>> set;
set.insert(10); // Insert a value into the set
```

**39. Using std::multiset with std::optional**

```cpp
std::multiset<std::optional<int>> mset;
mset.insert(10); // Insert a value into the multiset
```

**40. Using std::unordered\_set with std::optional**

```cpp
std::unordered_set<std::optional<int>> uset;
uset.insert(10); // Insert a value into the unordered set
```

**41. Using std::unordered\_multiset with std::optional**

```cpp
std::unordered_multiset<std::optional<int>> umset;
umset.insert(10); // Insert a value into the unordered multiset
```

**42. Using std::tuple with std::optional**

```cpp
std::tuple<std::optional<int>, std::optional<char>> tup;
tup = std::make_tuple(10, 'a'); // Initialize a tuple with optional elements
```

**43. Returning std::optional from a Function**

```cpp
std::optional<int> get_value() { return 10; } // Return an optional value from a function
```

**44. Throwing Exception from std::optional**

```cpp
if (!opt) { throw std::invalid_argument("Optional is empty"); } // Throw an exception if opt is empty
```

**45. Using std::make\_optional with Constructor**

```cpp
std::optional<std::pair<int, int>> opt_pair = std::make_optional(std::pair<int, int>(1, 2)); // Initialize an optional value with a constructor
```

**46. Using std::make\_optional with Factories**

```cpp
std::optional<std::string> opt_str = std::make_optional<std::string>("hello"); // Initialize an optional value with a factory function
```

**47. Using std::nullopt to Represent an Empty Value**

```cpp
std::optional<int> opt_empty = std::nullopt; // Initialize an empty optional value
```

**48. Using std::optional\_if to Initialize an Optional from a Condition**

```cpp
std::optional<int> opt_cond = std::optional_if(cond, value); // Initialize an optional value based on a condition
```

**49. Using std::transform with std::optional to Convert Types**

```cpp
std::transform(std::begin(opt1), std::end(opt1), std::back_inserter(vec), [](auto&& val) { return std::string(val.value()); }); // Transform the optional values to strings
```

**50. Using std::accumulate with std::optional to Aggregate Values**

```cpp
std::accumulate(std::begin(opt1), std::end(opt1), 0, [](auto&& sum, auto&& val) { return sum + val.value(); }); // Sum the optional values
```
