-
Book Overview & Buying
-
Table Of Contents
-
Feedback & Rating

Boost C++ Application Development Cookbook
By :

Imagine that we have a function that does not throw an exception and returns a value or indicates that an error has occurred. In Java or C# programming languages, such cases are handled by comparing a return value from a function value with a null
pointer. If the function returned null
, then an error has occurred. In C++, returning a pointer from a function confuses library users and usually requires slow dynamic memory allocation.
Only basic knowledge of C++ is required for this recipe.
Ladies and gentlemen, let me introduce you to the Boost.Optional
library using the following example:
The try_lock_device()
function tries to acquire a lock for a device and may succeed or not, depending on different conditions (in our example it depends on some try_lock_device_impl()
function call):
#include <boost/optional.hpp> #include <iostream> class locked_device { explicit locked_device(const char* /*param*/) { // We have unique access to device. std::cout << "Device is locked\n"; } static bool try_lock_device_impl(); public: void use() { std::cout << "Success!\n"; } static boost::optional<locked_device> try_lock_device() { if (!try_lock_device_impl()) { // Failed to lock device. return boost::none; } // Success! return locked_device("device name"); } ~locked_device(); // Releases device lock. };
The function returns the boost::optional
variable that can be converted to a bool
. If the returned value is equal to true
, then the lock is acquired and an instance of a class to work with the device can be obtained by dereferencing the returned optional variable:
int main() { for (unsigned i = 0; i < 10; ++i) { boost::optional<locked_device> t = locked_device::try_lock_device(); // optional is convertible to bool. if (t) { t->use(); return 0; } else { std::cout << "...trying again\n"; } } std::cout << "Failure!\n"; return -1; }
This program will output the following:
...trying again
...trying again
Device is locked
Success!
The default constructed optional
variable is convertible to false
and must not be dereferenced, because such an optional
does not have an underlying type constructed.
boost::optional<T>
under the hood has a properly aligned array of bytes where the object of type T
can be an in-place constructed. It also has a bool
variable to remember the state of the object (is it constructed or not?).
The Boost.Optional
class does not use dynamic allocation and it does not require a default constructor for the underlying type. The current boost::optional
implementation can work with C++11 rvalue references but is not usable with constexpr.
If you have a class T
that has no empty state but your program logic requires an empty state or uninitialized T
, then you have to come up with some workaround. Traditionally, users create some smart pointer to the class T
, keep a nullptr
in it, and dynamically allocate T
if non empty state is required. Stop doing that! Use boost::optional<T>
instead. It's a much faster and more reliable solution.
The C++17 standard includes the std::optional
class. Just replace <boost/optional.hpp>
with <optional>
and boost::
with std::
to use the standard version of this class. std::optional
is usable with constexpr.
Boost's official documentation contains more examples and describes advanced features of Boost.Optional
(like in-place construction). The documentation is available at the following link: http://boost.org/libs/optional.
Change the font size
Change margin width
Change background colour