czchlong
czchlong

Reputation: 2574

How to use boost::optional<T> to return NULL in C++?

I have a function that needs to return NULL in some cases and there is another function that needs to test for the return value of this function. I am aware of boost::optional but am not sure how to use the syntax.

Below would be a simple example of said usage:

int funct1(const string& key) {
  // use iterator to look for key in a map
  if(iterator == map.end()) {
    return NULL // need help here!
  else
    return it->second;
}

void funct2(string key) {
  if(funct1(key) == NULL) { // <-- need help here!
    // do something
  } else {
    // do something else
  }

Can someone please help with the syntax?

Thanks.

Upvotes: 9

Views: 14419

Answers (3)

rerun
rerun

Reputation: 25495

It stays in the "NULL" state until you set it. You can use this idiom:

optional<int> funct1(const string& key) {
  // use iterator to look for key in a map
  optional<int> ret; 
  if (iterator != map.end()) 
  {
    ret =  it->second;
  }

  return ret;
}

Then:

if (!funct1(key)) { /* no value */ }

Upvotes: 14

Mark B
Mark B

Reputation: 96241

Let me mention a few things before I get to the question.

If the string should always be found (programmer error if it's not) you should probably throw if it can't be instead of using an optional. You may even want to try/catch/throw even if it's user input.

If your class mimics container like semantics, you should consider using an end sentinel to indicate that it wasn't found, not null.

If however returning a null representation is what you're after, your function return type would be boost::optional<int> and the null return would be return boost::none;.

Upvotes: 4

Mark Ingram
Mark Ingram

Reputation: 73605

Try this:

int funct1(const string& key)
{
  // use iterator to look for key in a map
  if(iterator == map.end())
    return boost::optional<int>();
  else
    return boost::optional<int>(it->second);
}

void funct2(string key)
{
  const boost::optional<int> result = funct1(key);
  if (result.is_initialized())
  {
    // Value exists (use result.get() to access it)
  } 
  else
  {
    // Value doesn't exist
  }
}

I would also typedef the template, to make things easier:

typedef boost::optional<int> OptionalInt;

Upvotes: 1

Related Questions