Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I tell if a std::variant holds any value at all?

I already know how to use std::variant fairly well with std::get_if, std::get and std::visit. But what if I just want a simple way to tell if a variant has ever been initialized to any value? That is, I don’t care what the value is, I just want a boolean test. How do I do that?

For example, suppose I declare a variant on the stack

std::variant<int, double> data;

Then my function goes on and might or might not initialize this variable. At the end of my function I want to test if it was initialized

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • I looked at the index() function. That returns 0 both for an uninitialized variant and for one I intialize to the first type declared.
  • I looked valueless_by_exception() functions but that returns false whether I initialize the variant or not.

About the only thing I could think of to compare it to a default constructed one, like this)

using Data = std::variant<int, double>;

Data data

// ... code here that might initialize data or might not...

if (data = Data())
    // Not initialized
else
    // Initialized

This seems to work, but reading the comments on operator==() for std::variant, it seems like this behavior is undefined.

So is this a safe way to test? Or is there another?

>Solution :

std::variant<int, double> data;

data is initialized. A std::variant is always initialized with one of its values, unless it’s valueless_by_exception().

Unless a std::variant instance has an explicit constructor, the first variant alternative gets default-constructed. This specific data holds an int value, that’s default-constructed.

If the first std::variant value does not have a default constructor than the variant cannot be default-constructed, and must have an explicit constructor.

When it is desired to have a concept of a variant that doesn’t "really" (with the word "really" in air-quotes) have a default value: the usual convention is to have std::monostate as the first variant value. This is what std::monostate is for.

std::variant<std::monostate, int, double> data;

This variant is default-constructed and holds a std::monostate value. Its index() is 0. You can consider this variant to be uninitialized, whatever that actually means to your application, when your variant has a 0 index.

There’s nothing special about std::monostate itself. It’s just an empty class. If you visit a variant with a std::monostate value your visitor needs to deal with a std::monostate alternative.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading