failed attempt of using boost::optional

MistyD picture MistyD · Jun 4, 2013 · Viewed 8.4k times · Source

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;
}

Answer

awesoon picture awesoon · Jun 4, 2013

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;