How can I make sure that the boost :: optional <T> object is initialized in the release build?

When trying to get the value of the boost :: optional object, BOOST_ASSERT is used to make sure that the object is actually initialized.

But what I would like when the dereferencing of an uninitialized optional is an exception that needs to be thrown - is there a way to get this behavior in the release build? If not, is there another similar library that has this behavior?

I would really like to use the is_initialized method every time before dereferencing an object, and I would also like to avoid wrapping an optional class in my own class to get this behavior.

+3
source share
2 answers

Unfortunately, the option does not provide such an option. The entire option is optional in order to be able to check if this value is present using the overloaded bool operator.

Optional designed to allow NOT to execute exceptions in functions, but instead return success / failure.

Maybe you should always return a value instead and throw a function inside if it fails?

+3
source

You can define boost::assertion_failed(...)and BOOST_ENABLE_ASSERT_HANDLERto exclude exceptions from boost::optional.

The code:

#include<boost/exception/to_string.hpp>

namespace boost{
void assertion_failed(char const* expr, char const* function, char const* file, long line){
    throw std::runtime_error(std::string()
        + expr + 
        " from " + function +
        " at " + file + ":" + boost::to_string(line)
    );
}
}

#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/optional.hpp>
#undef BOOST_ENABLE_ASSERT_HANDLER

int main(){
    double d = *boost::optional<double>{}; // throws! (width fairly useful msg)
    (void)d;
}

An error message (if no exception is thrown) will read something like:

terminate called after throwing an instance of 'std::runtime_error'
  what():  this->is_initialized() from reference_type boost::optional<double>::get() [T = double] at /usr/include/boost/optional/optional.hpp:992

: http://boost.2283326.n4.nabble.com/optional-How-to-make-boost-optional-throw-if-trying-to-access-uninitialized-value-td2591333.html

:

1) assertion_failed, . , , assertion_failed ( ):

namespace boost{
void assertion_failed(char const* expr, char const* function, char const* file, long line){
    if(std::string("this->is_initialized()") == expr) throw std::domain_error("optional is not intialized");
    throw std::runtime_error(std::string()
        + expr + 
        " from " + function +
        " at " + file + ":" + boost::to_string(line)
    );
}
}

2) , , . assert . -, boost::optional .

3) std::experimental::optional. , * ( , - ) .value() std::experimental::bad_optional_access. ( assert s!, , , .).

+3

Source: https://habr.com/ru/post/1730185/


All Articles