Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparison (<), output (<<) and assignment (=) for boost::optional

I have a few questions about how boost::optional works. Let's first do this:

boost::optional<int> i;
  1. Is i < 3 always equivalent to *i < 3 (and similar for other relational operators)?
  2. Is it correct that the conditions i < 3 and *i < 3 are undefined? (i has still not been set to anything)
  3. What is std::cout << i supposed to print?
  4. I'm pretty sure that i = 3 is always the same as *i = 3. If so, which should I prefer?
like image 598
roger.james Avatar asked Jun 29 '13 23:06

roger.james


2 Answers

  1. No. If i is uninitialized, the first will return true while the second will assert.
  2. No. The documentation for operator< clearly indicates that if the lefthand argument is uninitialized it will return true when the righthand operand is set.
  3. There is no operator<< for optional so I assume it will return the unspecified-bool-type conversion and print 1 or 0 (true/false).
  4. They aren't the same. If i isn't initialized the latter will assert while the former will initialize-and-assign. You should use the one that indicates the semantics you desire.
like image 55
Mark B Avatar answered Oct 19 '22 21:10

Mark B


Regarding point 3, there is an operator<< for boost::optional declared in boost/optional/optional_io.hpp, but you probably aren't including that. (If you happen to use boost property_tree it gets included for you, though.) If it is included, an empty optional will stream as "--" and a populated optional will stream out an extra space character and then stream the value.

So this code:

#include <boost/optional/optional_io.hpp>
boost::optional<string> var1 = "value";
boost::optional<string> var2;
cout << " var1 = '" << var1 << "'\n";
cout << "*var1 = '" << *var1 << "'\n";
cout << " var2 = '" << var2 << "'\n";

yields this:

 var1 = ' value'
*var1 = 'value'
 var2 = '--'

but the same code without the include yields this, as suggested by Mark B's answer:

 var1 = '1'
*var1 = 'value'
 var2 = '0'

That extra space in the first case has caused me some confusion.

like image 41
codegardener Avatar answered Oct 19 '22 20:10

codegardener