7

I have been trying to use boost optional for a function that could either return an object or a null and I cant figure it out. Here is what I have so far. Any suggestions on how to resolve this issue would be appreciated.

class Myclass
{
public:
    int a;
};

boost::optional<Myclass> func(int a)  //This could either return MyClass or a null
{
    boost::optional<Myclass> value;
    if(a==0)
    {
        //return an object
            boost::optional<Myclass> value;
        value->a = 200;

    }
    else
    {
        return NULL;
    }

    return value;
}

int main(int argc, char **argv)
{
    boost::optional<Myclass> v = func(0);
    //How do I check if its a NULL or an object

    return 0;
}

Update:

This is my new code and I am getting a compiler error at value = {200};

class Myclass
{
public:
    int a;
};

boost::optional<Myclass> func(int a)
{
    boost::optional<Myclass> value;
    if(a == 0)
        value = {200};

    return value;
}

int main(int argc, char **argv)
{
    boost::optional<Myclass> v = func(0);


    if(v)
        std::cout << v -> a << std::endl;
    else
        std::cout << "Uninitilized" << std::endl;
    std::cin.get();

    return 0;
}
MistyD
  • 16,373
  • 40
  • 138
  • 240

1 Answers1

10

Your function should look like following:

boost::optional<Myclass> func(int a)
{
    boost::optional<Myclass> value;
    if(a == 0)
        value = {200};

    return value;
}

And you could check it by casting to bool:

boost::optional<Myclass> v = func(42);
if(v)
    std::cout << v -> a << std::endl;
else
    std::cout << "Uninitilized" << std::endl;

Isnt it going to be value->a = 200

No, it isn't. From Boost.Optional.Docs:

T const* optional<T (not a ref)>::operator ->() const ;

T* optional<T (not a ref)>::operator ->() ;
  • Requirements: *this is initialized.
  • Returns: A pointer to the contained value.
  • Throws: Nothing.
  • Notes: The requirement is asserted via BOOST_ASSERT().

And in the operator-> definition:

pointer_const_type operator->() const
{
    BOOST_ASSERT(this->is_initialized());
    return this->get_ptr_impl();
}

If object is not initialized, assertion will be failed. When we write

value = {200};

We initialize value with Myclass{200}.


Note, that value = {200} requires support for initializer lists(C++11 feature). If your compiler doesn't support it, you could use it like this:

Myclass c;
c.a = 200;
value = c;

Or provide constructor for Myclass with int as argument:

Myclass(int a_): a(a_)
{

}

Then you could just write

value = 200;
awesoon
  • 32,469
  • 11
  • 74
  • 99
  • I am confused with `value = {200}` Isnt it going to be `value->a = 200` ? – MistyD Jun 04 '13 at 05:20
  • Thanks for the edit. But with `value = {200};` I get the compile error during building `error C2143: syntax error : missing ';' before '{'` – MistyD Jun 04 '13 at 05:24
  • With this code, you would still end up with /usr/include/boost/optional/optional.hpp:1117: boost::optional::pointer_type boost::optional::operator->() [with T = Myclass; boost::optional::pointer_type = Myclass*]: Assertion `this->is_initialized()' failed. Aborted (core dumped) – badri Aug 11 '21 at 22:07
  • /* This results in the runtime error mentioned above */ value->a = {200}; /* The following #if 0 , if used instead would remove the error */ #if 0 Myclass c; c.a = 200; value = c; #endif – badri Aug 11 '21 at 22:07