SlideShare a Scribd company logo
1 of 25
Download to read offline
Discriminating unions
The Long Road to std::variant
Andreas Weis (@DerGhulbus)
Munich C++ User Group, November 2015
What is this ’variant’ people keep talking about?
Aka. tagged union, disjoint union, discriminated union. . .
Basically a strongly-typed union. Think:
enum class Tag { Integer , Float , String };
struct Variant {
Tag tag;
union Value {
int i;
float f;
std:: string str;
} value;
};
Algebraic sum data type. Dual to std::tuple.
Example
variant <int , float , std::string > v = 42;
int n = get <int >(v);
v = std:: string("Narf");
std:: string s = get <string >(v);
float f = get <float >(v); // *boom*
Example
struct Circle { float getArea () const; };
struct Square { float getArea () const; };
struct Triangle { float getArea () const; };
typedef variant <Circle , Square , Triangle > Shape;
struct GetShapeAreaVisitor {
template <typename T>
float operator ()(T const& s) {
return s.getArea ();
}
};
float getArea(Shape const& s) {
return visit( GetShapeAreaVisitor {}, s);
}
Previous Work
Alexandrescu
An Implementation of Discriminated Unions in C++,
Template Programming Workshop, OOPSLA 2001
Dr. Dobb’s Generic Programming: Discriminated Unions, 2002
Friedman - Boost.Variant, 2003
Berg - Eggs.Variant, 2014
Early approaches were constrained by C++98.
People love variants!
Someone should write a proposal. . .
Refresher: Exception Safety Guarantees
Possible exception safety guarantees for a function func():
noexcept - func() will not throw an exception.
Strong exception guarantee - If func() throws, the program
state will be left unchanged (as if the call never happened).
Basic exception guarantee - If func() throws, the program
will be left in a valid state (for member functions, usually
allows at least assignment-to and destruction of the object).
Variant assignment
std:: string teststring("Lorem ipsum dolor sit");
std:: variant <int , std::string > v1 (42);
v1 = teststring;
What if the copy assignment for std::string throws?
This is different from std::optional! We switch types during
assignment.
What would Boost do?
boost::variant gives a never-empty guarantee.
For a variant<T1,T2,...,TN> one of the Ts is always held
in storage.
Default construction always default-constructs T1.
Uses double-buffering for assignment.
A temporary storage is allocated on the heap and holds a copy
of the original data while the assignment takes place.
Disadvantages: Heap allocation required. Order of operations is
unintuitive.
N4218 - Variant v1
First proposal by Axel Naumann in September 2014.
Double-buffering was deemed too inefficient.
variant reverts to an empty state upon default construction
and throwing assignment.
Emptyness can be queried through empty() member function.
get() will throw when empty.
Disadvantages?
N4450 - Variant v2
Naumann, April 2015.
In Urbana it was decided that the initial variant TS should include
visitors.
How to visit a variant that can be empty?
struct Visitor {
template <typename Ti >
void operator ()(Ti) { /* variant types */ }
void operator ()() { /* empty type */ }
};
variant v;
visit(Visitor (), v);
N4450 - Variant v2
struct Visitor {
template <typename Ti >
void operator ()(Ti) { /* variant types */ }
};
struct EmptyVisitor {
void operator ()() { /* empty type */ }
};
variant v;
visit(Visitor (), EmptyVisitor (), v);
N4516, N4242 - Variant v3/v4
Naumann, May 2015.
Variants were heavily discussed in Lenexa, which led to a number
of changes.
!empty() becomes valid().
The invalid state is restricted to failed assignments.
Default construction now uses the first type (just like union
and boost::variant). Type monostate to explicitly enable
default construction.
Accessing the invalid state is UB. The empty visitor goes away.
The change from empty to invalid is bigger than it might seem at
first glance.
A. Williams - Standardizing Variant: Difficult Decisions
Blog post on Williams’ private blog in June 2015. Spawns
numerous discussions in the blog comments, on Reddit, and the
ISO mailing list.
Williams argues that UB for accessing invalid variants is too
hard to check.
get() should throw instead. Copying from an invalid variant
should be possible
Niebler argues that invalid is not a problem as it can only
happen if an assignment fails with exception.
Surely they will be able to figure this out before Kona. . .
p0088r0 - Variant v5 - a type-safe union that is rarely
invalid
Mostly a cleaned-up version of v4.
Completely removes the notion of the empty type.
Invalid state is observable through member functions valid()
and index().
Accessing the invalid state is still UB.
But invalid variants can now be assigned-from.
p0080r - Discriminated Union with Value Semantics
July 2015, Alternative proposal by Michael Park
After throwing assignment everything except assign-to and
destruct is UB. Unlike N4542, indeterminate state here is
unobservable.
Default construct to indeterminate state.
New nullstate type allows to opt-in for a safe fallback type.
Visitation is handled completely different.
p0093r0 - Simply a Strong Variant
David Sankel, September 2015
Argues that invalid state is problematic as it has no analogy in
mathematical discriminated unions.
Strong exception guarantee is easy if types allow non-throw
move construction.
Use in-place double-buffering if one of the alternative types
can throw on move-construction.
Argues that the user can always declare noexcept move
constructor to get rid of double-buffering.
Basically an old-school boost::variant with some C++11
tuning.
p0094r0 - Simply a Basic Variant
David Sankel, September 2015
Who needs strong exception safety anyway?
If assignment throws, default construct one of the alternative
types.
Never empty is guaranteed, though we don’t know what will
be in there.
Use double-buffering as fallback if none of the types is
nothrow default constructible.
...and more!
p0095r0 - Sankel, The Case for a Language Based Variant:
We are doomed! Compiler writers, save us!
p0087r0 - Naumann, A type-safe union without undefined
behavior: Variant v2-b. Maybe we need to go back to where
we started.
p0110 - Williams, Implementing the strong guarantee for
variant assignment: Do the most efficient thing possible given
the nothrow guarantees of the types. Still has to fallback to
double-buffering in pathological case.
Total of 8 proposals discussing variant in September 2015.
The Kona Kompromise - A happy ending?
Kona Trip Report by Naumann, October 2015.1
Basically v5, but get() will throw if invalid.
No more undefined behavior!
No more assert(v.valid()) cluttering your code!
Strong exception safety for non-throwing move; Basic
exception safety otherwise.
“Almost everyone in the room was happy!”
Re-review pending for the Jacksonville meeting in March 2016.
1
https://isocpp.org/blog/2015/11/the-variant-saga-a-happy-ending
Conclusion
There is no obvious right answer for default construction and
throwing assignment.
People do care about variant.
Discussions can be chaotic, but will be worth it if we can work
it out.
Thanks for your attention.

More Related Content

Similar to Discriminating unions - The Long Road to std::variant

C#3.0 & Vb 9.0 Language Enhancments
C#3.0 & Vb 9.0 Language EnhancmentsC#3.0 & Vb 9.0 Language Enhancments
C#3.0 & Vb 9.0 Language Enhancmentstechfreak
 
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source CodeA Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source CodePVS-Studio
 
Identifiers, keywords and types
Identifiers, keywords and typesIdentifiers, keywords and types
Identifiers, keywords and typesDaman Toor
 
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...PVS-Studio
 
Static Keyword Static is a keyword in C++ used to give special chara.pdf
  Static Keyword Static is a keyword in C++ used to give special chara.pdf  Static Keyword Static is a keyword in C++ used to give special chara.pdf
Static Keyword Static is a keyword in C++ used to give special chara.pdfKUNALHARCHANDANI1
 
C++ Interview Question And Answer
C++ Interview Question And AnswerC++ Interview Question And Answer
C++ Interview Question And AnswerJagan Mohan Bishoyi
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answerlavparmar007
 
Sony C#/.NET component set analysis
Sony C#/.NET component set analysisSony C#/.NET component set analysis
Sony C#/.NET component set analysisPVS-Studio
 
More Little Wonders of C#/.NET
More Little Wonders of C#/.NETMore Little Wonders of C#/.NET
More Little Wonders of C#/.NETBlackRabbitCoder
 
Classification case study + intro to cnn
Classification case study + intro to cnnClassification case study + intro to cnn
Classification case study + intro to cnnVincent Tatan
 
JAVA(module1).pptx
JAVA(module1).pptxJAVA(module1).pptx
JAVA(module1).pptxSRKCREATIONS
 
Prefix casting versus as-casting in c#
Prefix casting versus as-casting in c#Prefix casting versus as-casting in c#
Prefix casting versus as-casting in c#Paul Houle
 
Kyo - Functional Scala 2023.pdf
Kyo - Functional Scala 2023.pdfKyo - Functional Scala 2023.pdf
Kyo - Functional Scala 2023.pdfFlavio W. Brasil
 
Kotlin what_you_need_to_know-converted event 4 with nigerians
Kotlin  what_you_need_to_know-converted event 4 with nigeriansKotlin  what_you_need_to_know-converted event 4 with nigerians
Kotlin what_you_need_to_know-converted event 4 with nigeriansjunaidhasan17
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantKevlin Henney
 

Similar to Discriminating unions - The Long Road to std::variant (20)

C#3.0 & Vb 9.0 Language Enhancments
C#3.0 & Vb 9.0 Language EnhancmentsC#3.0 & Vb 9.0 Language Enhancments
C#3.0 & Vb 9.0 Language Enhancments
 
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source CodeA Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
 
Identifiers, keywords and types
Identifiers, keywords and typesIdentifiers, keywords and types
Identifiers, keywords and types
 
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
 
Static Keyword Static is a keyword in C++ used to give special chara.pdf
  Static Keyword Static is a keyword in C++ used to give special chara.pdf  Static Keyword Static is a keyword in C++ used to give special chara.pdf
Static Keyword Static is a keyword in C++ used to give special chara.pdf
 
C++ Interview Question And Answer
C++ Interview Question And AnswerC++ Interview Question And Answer
C++ Interview Question And Answer
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answer
 
Sony C#/.NET component set analysis
Sony C#/.NET component set analysisSony C#/.NET component set analysis
Sony C#/.NET component set analysis
 
C# features
C# featuresC# features
C# features
 
More Little Wonders of C#/.NET
More Little Wonders of C#/.NETMore Little Wonders of C#/.NET
More Little Wonders of C#/.NET
 
Synapseindia dot net development
Synapseindia dot net developmentSynapseindia dot net development
Synapseindia dot net development
 
Effective Java
Effective JavaEffective Java
Effective Java
 
Classification case study + intro to cnn
Classification case study + intro to cnnClassification case study + intro to cnn
Classification case study + intro to cnn
 
JAVA(module1).pptx
JAVA(module1).pptxJAVA(module1).pptx
JAVA(module1).pptx
 
Prefix casting versus as-casting in c#
Prefix casting versus as-casting in c#Prefix casting versus as-casting in c#
Prefix casting versus as-casting in c#
 
Kyo - Functional Scala 2023.pdf
Kyo - Functional Scala 2023.pdfKyo - Functional Scala 2023.pdf
Kyo - Functional Scala 2023.pdf
 
From DOT to Dotty
From DOT to DottyFrom DOT to Dotty
From DOT to Dotty
 
Kotlin what_you_need_to_know-converted event 4 with nigerians
Kotlin  what_you_need_to_know-converted event 4 with nigeriansKotlin  what_you_need_to_know-converted event 4 with nigerians
Kotlin what_you_need_to_know-converted event 4 with nigerians
 
Intake 37 2
Intake 37 2Intake 37 2
Intake 37 2
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
 

Recently uploaded

TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 

Recently uploaded (20)

TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 

Discriminating unions - The Long Road to std::variant

  • 1. Discriminating unions The Long Road to std::variant Andreas Weis (@DerGhulbus) Munich C++ User Group, November 2015
  • 2. What is this ’variant’ people keep talking about? Aka. tagged union, disjoint union, discriminated union. . . Basically a strongly-typed union. Think: enum class Tag { Integer , Float , String }; struct Variant { Tag tag; union Value { int i; float f; std:: string str; } value; }; Algebraic sum data type. Dual to std::tuple.
  • 3. Example variant <int , float , std::string > v = 42; int n = get <int >(v); v = std:: string("Narf"); std:: string s = get <string >(v); float f = get <float >(v); // *boom*
  • 4. Example struct Circle { float getArea () const; }; struct Square { float getArea () const; }; struct Triangle { float getArea () const; }; typedef variant <Circle , Square , Triangle > Shape; struct GetShapeAreaVisitor { template <typename T> float operator ()(T const& s) { return s.getArea (); } }; float getArea(Shape const& s) { return visit( GetShapeAreaVisitor {}, s); }
  • 5. Previous Work Alexandrescu An Implementation of Discriminated Unions in C++, Template Programming Workshop, OOPSLA 2001 Dr. Dobb’s Generic Programming: Discriminated Unions, 2002 Friedman - Boost.Variant, 2003 Berg - Eggs.Variant, 2014 Early approaches were constrained by C++98.
  • 6. People love variants! Someone should write a proposal. . .
  • 7. Refresher: Exception Safety Guarantees Possible exception safety guarantees for a function func(): noexcept - func() will not throw an exception. Strong exception guarantee - If func() throws, the program state will be left unchanged (as if the call never happened). Basic exception guarantee - If func() throws, the program will be left in a valid state (for member functions, usually allows at least assignment-to and destruction of the object).
  • 8. Variant assignment std:: string teststring("Lorem ipsum dolor sit"); std:: variant <int , std::string > v1 (42); v1 = teststring; What if the copy assignment for std::string throws? This is different from std::optional! We switch types during assignment.
  • 9.
  • 10. What would Boost do? boost::variant gives a never-empty guarantee. For a variant<T1,T2,...,TN> one of the Ts is always held in storage. Default construction always default-constructs T1. Uses double-buffering for assignment. A temporary storage is allocated on the heap and holds a copy of the original data while the assignment takes place. Disadvantages: Heap allocation required. Order of operations is unintuitive.
  • 11. N4218 - Variant v1 First proposal by Axel Naumann in September 2014. Double-buffering was deemed too inefficient. variant reverts to an empty state upon default construction and throwing assignment. Emptyness can be queried through empty() member function. get() will throw when empty. Disadvantages?
  • 12. N4450 - Variant v2 Naumann, April 2015. In Urbana it was decided that the initial variant TS should include visitors. How to visit a variant that can be empty? struct Visitor { template <typename Ti > void operator ()(Ti) { /* variant types */ } void operator ()() { /* empty type */ } }; variant v; visit(Visitor (), v);
  • 13. N4450 - Variant v2 struct Visitor { template <typename Ti > void operator ()(Ti) { /* variant types */ } }; struct EmptyVisitor { void operator ()() { /* empty type */ } }; variant v; visit(Visitor (), EmptyVisitor (), v);
  • 14.
  • 15. N4516, N4242 - Variant v3/v4 Naumann, May 2015. Variants were heavily discussed in Lenexa, which led to a number of changes. !empty() becomes valid(). The invalid state is restricted to failed assignments. Default construction now uses the first type (just like union and boost::variant). Type monostate to explicitly enable default construction. Accessing the invalid state is UB. The empty visitor goes away. The change from empty to invalid is bigger than it might seem at first glance.
  • 16. A. Williams - Standardizing Variant: Difficult Decisions Blog post on Williams’ private blog in June 2015. Spawns numerous discussions in the blog comments, on Reddit, and the ISO mailing list. Williams argues that UB for accessing invalid variants is too hard to check. get() should throw instead. Copying from an invalid variant should be possible Niebler argues that invalid is not a problem as it can only happen if an assignment fails with exception. Surely they will be able to figure this out before Kona. . .
  • 17. p0088r0 - Variant v5 - a type-safe union that is rarely invalid Mostly a cleaned-up version of v4. Completely removes the notion of the empty type. Invalid state is observable through member functions valid() and index(). Accessing the invalid state is still UB. But invalid variants can now be assigned-from.
  • 18. p0080r - Discriminated Union with Value Semantics July 2015, Alternative proposal by Michael Park After throwing assignment everything except assign-to and destruct is UB. Unlike N4542, indeterminate state here is unobservable. Default construct to indeterminate state. New nullstate type allows to opt-in for a safe fallback type. Visitation is handled completely different.
  • 19. p0093r0 - Simply a Strong Variant David Sankel, September 2015 Argues that invalid state is problematic as it has no analogy in mathematical discriminated unions. Strong exception guarantee is easy if types allow non-throw move construction. Use in-place double-buffering if one of the alternative types can throw on move-construction. Argues that the user can always declare noexcept move constructor to get rid of double-buffering. Basically an old-school boost::variant with some C++11 tuning.
  • 20. p0094r0 - Simply a Basic Variant David Sankel, September 2015 Who needs strong exception safety anyway? If assignment throws, default construct one of the alternative types. Never empty is guaranteed, though we don’t know what will be in there. Use double-buffering as fallback if none of the types is nothrow default constructible.
  • 21. ...and more! p0095r0 - Sankel, The Case for a Language Based Variant: We are doomed! Compiler writers, save us! p0087r0 - Naumann, A type-safe union without undefined behavior: Variant v2-b. Maybe we need to go back to where we started. p0110 - Williams, Implementing the strong guarantee for variant assignment: Do the most efficient thing possible given the nothrow guarantees of the types. Still has to fallback to double-buffering in pathological case. Total of 8 proposals discussing variant in September 2015.
  • 22.
  • 23. The Kona Kompromise - A happy ending? Kona Trip Report by Naumann, October 2015.1 Basically v5, but get() will throw if invalid. No more undefined behavior! No more assert(v.valid()) cluttering your code! Strong exception safety for non-throwing move; Basic exception safety otherwise. “Almost everyone in the room was happy!” Re-review pending for the Jacksonville meeting in March 2016. 1 https://isocpp.org/blog/2015/11/the-variant-saga-a-happy-ending
  • 24. Conclusion There is no obvious right answer for default construction and throwing assignment. People do care about variant. Discussions can be chaotic, but will be worth it if we can work it out.
  • 25. Thanks for your attention.