What is std::nullopt in C++?

In C++, std::nullopt is a value that represents the absence of a value. It’s part of the <optional> header introduced in C++17. Before C++17, developers often used sentinel values like -1, nullptr, or other special constants to indicate the absence of a value. However, these approaches were error-prone and didn’t convey the intent clearly. The introduction of std::nullopt addresses these issues by providing a standardized way to represent the absence of a value.

Why use std::nullopt?

Using std::nullopt has several benefits:

1. Improved clarity: By using std::nullopt, we can explicitly convey the absence of a value in our code. This makes our code more self-documenting and helps other developers understand our intentions.

2. Type safety: The std::nullopt value is type-safe. It can be used with any type, and the compiler will catch type-related errors at compile-time, reducing runtime errors and bugs.

3. Compatibility with std::optional: The std::nullopt value is commonly used in conjunction with std::optional, which is a C++17 feature that represents an optional value. When we assign std::nullopt to an std::optional, we explicitly set it to a state with no value.

How to use std::nullopt

Using std::nullopt is straightforward. Here’s how we can use it:

#include <iostream>
#include <optional>
int main() {
std::optional<int> maybeValue;
// Assigning no value
maybeValue = std::nullopt;
if (!maybeValue.has_value()) {
std::cout << "No value assigned to maybeValue." << std::endl;
}
return 0;
}
How to use std::nullopt

In the example above, we create an std::optional<int> called maybeValue and assign std::nullopt to it. The has_value() function is used to check if a value is assigned.

Returning std::nullopt

We can also use std::nullopt to indicate that a function couldn’t produce a valid result, as shown below:

#include <iostream>
#include <optional>
std::optional<int> divide(int numerator, int denominator) {
if (denominator == 0) {
return std::nullopt; // Indicates an error
}
return numerator / denominator;
}
int main()
{
int numerator[] = {10, 8, 6, 4, 2, 1};
int denominator[] = {5, 4, 3, 2, 1, 0};
for(int i = 0; i < 6; i++)
{
std::cout << i+1 <<".\t Numerator: " << numerator[i] << std::endl;
std::cout << "\t Denominator: " << denominator[i] << std::endl;
std::optional<int> result = divide(numerator[i], denominator[i]);
if (result.has_value())
{
std::cout << "\t Result: " << result.value() << std::endl;
}
else
{
std::cout << "\t Error: Division by zero!" << std::endl;
}
std::cout << std::string(100, '-') << std::endl;
}
return 0;
}
Returning std::nullopt

In the example above, the divide function returns std::nullopt when the denominator is zero, indicating that the division operation couldn’t be performed.

The std::nullopt feature is a valuable addition to modern C++ that enhances code clarity and type safety when dealing with optional values. Knowing features like std::nullopt will help to write more robust and maintainable code.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved