polapts polapts - 22 days ago 14
C++ Question

How to use boost::optional

I am trying to use

as below.

#include <iostream>
#include <string>

#include <boost/optional.hpp>

struct myClass
{
int myInt;
void setInt(int input) { myInt = input; }
int getInt(){return myInt; }
};

boost::optional<myClass> func(const std::string &str)
{
boost::optional<myClass> value;
if(str.length() > 5)
{
// If greater than 5 length string. Set value to 10
value.get().setInt(10);
}
else if (str.length() < 5)
{
// Else set it to 0
value.get().setInt(0);
}
else
{
// If it is 5 set the value to 5
value.get().setInt(5);
}

return value;
}


int main()
{
boost::optional<myClass> v1 = func("3124");
boost::optional<myClass> v2 = func("helloWorld");
boost::optional<myClass> v3 = func("hello");

if (v1)
std::cout << "v1 is valid" << std::endl;
else
std::cout << "v1 is not valid" << std::endl;

if (v2)
std::cout << "v2 is valid" << std::endl;
else
std::cout << "v3 is not valid" << std::endl;

if (v3)
std::cout << "v3 is valid" << std::endl;
else
std::cout << "v3 is not valid" << std::endl;

return 0;
}


I get following error


prog.exe:
/usr/local/boost-1.55.0/include/boost/optional/optional.hpp:631:
boost::optional::reference_type boost::optional::get() [with T =
myClass; boost::optional::reference_type = myClass&]: Assertion
`this->is_initialized()' failed.


Presumably, the optional variable is not initialized properly. How to do it the correct way?

EDIT:: Got some very good answers, just couple of more questions 1. Is it a good idea to use
make_optional
at the end of
'func'
function and return it? Also 2. I was thinking of assigning
boost::none
to emphasize that I have no value to assign and that's why
boost::none
. But not sure if that is valid?

Answer

A default-constructed boost::optional is empty - it does not contain a value, so you can't call get() on it. You have to initialise it with a valid value:

boost::optional<myClass> value = myClass();

Alternatively, you can use an in-place factory to avoid copy initialisation (but the copy will most likely be elided anyway); however, I have no experience with that, so I can't provide an example.


As a side note, you can use -> in place of get(), like this:

value->setInt(10);

But that's just a matter of stylistic preference, both are equally valid.

Comments