Defensive Programming
Optional Results
std::optional represents a result that might not exist.
optional result
An optional result makes the missing case visible without inventing a fake value.
Optional Results
optional_results.cpp
Replay: real traced execution (multi-file project)
#include <iostream>
#include <optional>
#include <string>
#include <vector>
std::optional<int> findPrice(const std::vector<std::pair<std::string, int>>& prices,
const std::string& item) {
for (const auto& entry : prices) {
if (entry.first == item) {
return entry.second;
}
}
return std::nullopt;
}
int main() {
std::vector<std::pair<std::string, int>> prices{{"pencil", 2}, {"notebook", 5}};
std::string item = "pencil";
std::optional<int> price = findPrice(prices, item);
std::cout << "item=" << item << std::endl;
if (price.has_value()) {
std::cout << "price=" << price.value() << std::endl;
} else {
std::cout << "price=missing" << std::endl;
}
return 0;
}
#include <iostream>
#include <optional>
#include <string>
#include <vector>
std::optional<int> findPrice(const std::vector<std::pair<std::string, int>>& prices,
const std::string& item) {
for (const auto& entry : prices) {
if (entry.first == item) {
return entry.second;
}
}
return std::nullopt;
}
int main() {
std::vector<std::pair<std::string, int>> prices{{"pencil", 2}, {"notebook", 5}};
std::string item = "notebook";
std::optional<int> price = findPrice(prices, item);
std::cout << "item=" << item << std::endl;
if (price.has_value()) {
std::cout << "price=" << price.value() << std::endl;
} else {
std::cout << "price=missing" << std::endl;
}
return 0;
}
#include <iostream>
#include <optional>
#include <string>
#include <vector>
std::optional<int> findPrice(const std::vector<std::pair<std::string, int>>& prices,
const std::string& item) {
for (const auto& entry : prices) {
if (entry.first == item) {
return entry.second;
}
}
return std::nullopt;
}
int main() {
std::vector<std::pair<std::string, int>> prices{{"pencil", 2}, {"notebook", 5}};
std::string item = "marker";
std::optional<int> price = findPrice(prices, item);
std::cout << "item=" << item << std::endl;
if (price.has_value()) {
std::cout << "price=" << price.value() << std::endl;
} else {
std::cout << "price=missing" << std::endl;
}
return 0;
}
prices ← (empty), item ← pencil
16int main() {17 std::vector<std::pair<std::string, int>> prices→ (empty){{"pencil", 2}, {"notebook", 5}};18 std::string item→ pencil = "pencil"; //@item="notebook", "marker"1920 std::optional<int> price = findPrice(prices, item);std::optional<int> findPrice(const std::vector<std::pair<std::string, …
6std::optional<int> findPrice(const std::vector<std::pair<std::string, int>>& prices(empty),7 const std::string& itempencil) {8 for (const auto& entry : prices) {for (const auto& entry : prices)
7 const std::string& item) {8for (const auto& entry(empty) : prices(empty)) {9 if (entry.first == item) {if (entry.first == item)
8for (const auto& entry : prices) {9 if (entry(empty).first == itempencil) {10 return entry.second2;11 }std::cout << "item=" << item << std::endl;
20std::optional<int> price = findPrice(prices, item);2122std::cout << "item=" << itempencil << std::endl;23if (price.has_value()) {outputitem=pencilif (price.has_value())
22std::cout << "item=" << item << std::endl;23if (price.has_value()) {24 std::cout << "price=" << price.value() << std::endl;25} else {outputprice=2return 0;
27 }28 return 0;29}
prices ← (empty), item ← notebook
16int main() {17 std::vector<std::pair<std::string, int>> prices→ (empty){{"pencil", 2}, {"notebook", 5}};18 std::string item→ notebook = "notebook";1920 std::optional<int> price = findPrice(prices, item);std::optional<int> findPrice(const std::vector<std::pair<std::string, …
6std::optional<int> findPrice(const std::vector<std::pair<std::string, int>>& prices(empty),7 const std::string& itemnotebook) {8 for (const auto& entry : prices) {for (const auto& entry : prices)
pass 1 of 27 const std::string& item) {8for (const auto& entry(empty) : prices(empty)) {9 if (entry.first == item) {for (const auto& entry : prices)
pass 2 of 27 const std::string& item) {8for (const auto& entry(empty) : prices(empty)) {9 if (entry.first == item) {if (entry.first == item)
8for (const auto& entry : prices) {9 if (entry(empty).first == itemnotebook) {10 return entry.second5;11 }std::cout << "item=" << item << std::endl;
20std::optional<int> price = findPrice(prices, item);2122std::cout << "item=" << itemnotebook << std::endl;23if (price.has_value()) {outputitem=notebookif (price.has_value())
22std::cout << "item=" << item << std::endl;23if (price.has_value()) {24 std::cout << "price=" << price.value() << std::endl;25} else {outputprice=5return 0;
27 }28 return 0;29}
prices ← (empty), item ← marker
16int main() {17 std::vector<std::pair<std::string, int>> prices→ (empty){{"pencil", 2}, {"notebook", 5}};18 std::string item→ marker = "marker";1920 std::optional<int> price = findPrice(prices, item);std::optional<int> findPrice(const std::vector<std::pair<std::string, …
6std::optional<int> findPrice(const std::vector<std::pair<std::string, int>>& prices(empty),7 const std::string& itemmarker) {8 for (const auto& entry : prices) {for (const auto& entry : prices)
pass 1 of 27 const std::string& item) {8for (const auto& entry(empty) : prices(empty)) {9 if (entry.first == item) {for (const auto& entry : prices)
pass 2 of 27 const std::string& item) {8for (const auto& entry(empty) : prices(empty)) {9 if (entry.first == item) {return std::nullopt;
12 }13 return std::nullopt;14}std::cout << "item=" << item << std::endl;
20std::optional<int> price = findPrice(prices, item);2122std::cout << "item=" << itemmarker << std::endl;23if (price.has_value()) {outputitem=markerelse
24 std::cout << "price=" << price.value() << std::endl;25} else {26 std::cout << "price=missing" << std::endl;27}outputprice=missingreturn 0;
27 }28 return 0;29}