18

I'm trying to understand when is the right time to use some of the structures that come with boost and had a question regarding the use of boost::optional with a reference.

Suppose I have the following class, using boost::optional:

class MyClass {
public:
   MyClass() {}

   initialise(Helper& helper) {
      this->helper = helper;
   }

   boost::optional<Helper&> getHelper() {
      return helper;
   }

private:
   boost::optional<Helper&> helper;
}

Why would I use the above instead of:

class MyClass {
public:
   MyClass() : helper(nullptr) {}

   initialise(Helper& helper) {
      this->helper = &helper;
   }

   Helper* getHelper() {
      return helper;
   }

private:
   Helper* helper;
}

They both convey the same intent, i.e. that getHelper could return null, and the caller still needs to test if a helper was returned.

Should you only be using boost::optional if you need to know the difference between 'a value', nullptr and 'not a value'?

B Faley
  • 17,120
  • 43
  • 133
  • 223
Lee
  • 303
  • 3
  • 6
  • boost::optional just wrapper of T*. Prefer T* than boost::optional due to boost::optional is weird in C++. T* has better readability – jean Aug 03 '17 at 03:46

2 Answers2

20

Compared to a raw pointer, an optional reference may suggest that (1) pointer arithmetic is not used, and (2) ownership of the referent is maintained elsewhere (so delete will clearly not be used with the variable).

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
20

Great question, and John Zwinck's answer above is right. However, some people (e.g., many on the standardization committee), doubt whether these reasons are enough to justify the existence of optional<T&>, when optional<T&> can have such confusing semantics. Consider what should happen when you assign to one of these guys. Should it re-seat the reference (i.e., make it point to a different object), or assign through the reference, like a real T& does? A case can be made for either, which would cause confusion and subtle bugs. Support for optional<T&> was removed from the proposal that recently got accepted into the C++14.

In short, if you want to make your code portable to C++14's std::optional, prefer T* over boost::optional<T&>.

Eric Niebler
  • 5,927
  • 2
  • 29
  • 43