Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use boost::optional

I am trying to use boost::optional 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?

like image 809
polapts Avatar asked Mar 06 '14 14:03

polapts


People also ask

How does boost optional work?

boost::optional appears to work like a pointer. However, you should not think of boost::optional as a pointer because, for example, values in boost::optional are copied by the copy constructor while a pointer does not copy the value it points to.

How do I get the value of a boost optional?

You could use the de-reference operator: SomeClass sc = *val; Alternatively, you can use the get() method: SomeClass sc = val.

What is boost none?

The expression boost::none denotes an instance of boost::none_t that can be used as the parameter. Example: #include <boost/none.hpp> optional<int> n(boost::none) ; assert ( ! n ) ; optional<T (not a ref)>::optional( T const& v ) Effect: Directly-Constructs an optional.

What is boost any?

The boost::any class (based on the class of the same name described in "Valued Conversions" by Kevlin Henney, C++ Report 12(7), July/August 2000) is a variant value type based on the second category. It supports copying of any value type and safe checked extraction of that value strictly against its type.


1 Answers

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.

like image 115
Angew is no longer proud of SO Avatar answered Sep 25 '22 17:09

Angew is no longer proud of SO