Search code examples
c++boostboost-optional

passing boost::optional lvalue as a reference to a function


Can you somehow pass boost::optional lvalue as a reference into a function which changes the value? Something like this (http://coliru.stacked-crooked.com/a/f77d3b095af3d66b):

#include <iostream>

#include <boost/optional.hpp>

void foo(int& x)
{
    x = 3;
}

int main() {
    boost::optional<int> y;
    foo(*y);
    std::cout << *y << std::endl;
}

which doesn't work, unsurprisingly.

The function needs to use standard type as the output argument tho (e.g. int& x). I hope I am explaining this correctly. I am asking about general possibility of my intention.


Solution

  • Yes. you just have to initialize the optional like your compilation error suggests:

    boost::optional::reference_type boost::optional::get() [with T = int; boost::optional::reference_type = int&]: Assertion `this->is_initialized()' failed.

    This works & prints 3:

    #include <iostream>
    #include <boost/optional.hpp>
    
    void foo(int& x)
    {
        x = 3;
    }
    
    int main() {
        boost::optional<int> y = 2;
        foo(*y);
        std::cout << *y << std::endl;
    }
    

    An important remark noted by the op, is that even if the initialization value is not known in compile time, boost will anyway assert the optional's state (on operator* or on get()), which means that if the optional is not set (boost::none) the application will crash.

    So one can either initialize with a valid-value-containing optional (non boost::none), or pass optional<int>&.