Skip to content

Instantly share code, notes, and snippets.

@masters3d
Last active July 29, 2018 03:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masters3d/24580156bb38e84a97fdb87d6436a934 to your computer and use it in GitHub Desktop.
Save masters3d/24580156bb38e84a97fdb87d6436a934 to your computer and use it in GitHub Desktop.
Write up on the C++11 optional feature.

std::optional

I chose the new C++17 feature called std::optional. I am attracted to this feature because I am a big fan of the optional type in Swift and others languages like TypeScript and C#. The main idea behind optional is that is meant to address the fact that not all types are meant to be null. Languages like Rust and Swift (which market themselves as the next C++ killer) emerged around 2010-2015 already with the idea of optionals from the get-go.

#include "stdafx.h"
#include <optional>
#include <string>
#include <iostream>

// Pre Optional
std::string convert(int value)
{
	return value == 1 ? "one" : value == 0 ? "zero" : "unknown";
}

// With Optional
auto convertBinary(int value)
{
	return value == 1 ? std::optional<std::string>{"one"} : (value == 0 ? std::optional<std::string>{"zero"} : std::nullopt);
}

// Pre Optional
void print(std::string input)
{
	std::cout << input << std::endl;
}
// With Optional
void print(std::optional<std::string> input, std::string fallback)
{
	std::cout << input.value_or(fallback) << std::endl;
}


int main()
{

	std::optional<std::string> someString;

	print(someString, "no value provided"); // "no value provided" prints
	
	someString = "I have a value now";
	
	print(someString, "no value provided"); // The value prints

	std::string anotherString;

	print(anotherString); // Nothing prints

	return 0;
}

Languages like Java and C# have been trying to retrofit the idea of optionals in the language but this is not going well. Most people do not like to change their mental model of reference types equaling nullable types. Languages that try to separate those two ideas, later on, face a lot of opposition. Because of this, I believe that C++ chose to only support value types in this iteration. Since the idea of nullability being separate from a reference was never part of the main idea behind the language, most new APIs are not created with the affordances that the optional API provides. The main solution that we have to the Billion Dollar Mistake does not address the problem directly in C++17. C++ is going the same route that C# took when it introduces nullable value types. It is only half of a solution if the solution only works for values types. On the new version of C# (v 8), they are going address nullable references. I believe this is where C++ could have leaped into addressing this issue but as long as they are still thinking of adding support for reference types to be used within the optional type, then hopefully optional would be more useful than it is currently.

The optional type is great when you have a value type that you will you would be able to set to null. While the feature is not called directly a nullable wrapper, it does have the same effect. The only way to get the benefits for this template is to have the other packages that also use the type. Objective-C also faced a similar decision when it decided to introduced nullability tagging. After this feature was introduced most packages were encouraged to add nullability tagging to their packages so they could interact better with others. Making nullability explicit is a good thing. Perhaps types like std::string do not really need the optional type but numeral types like int can take advantage of optional instead of using default values like 0 or -1.

References Inlined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment