Search code examples
c++boost-optional

failed attempt of using boost::optional


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

Solution

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