Nick Heiner
Nick Heiner

Reputation: 122500

C++: Return NULL instead of struct

I have a struct Foo. In pseudocode:

def FindFoo:
   foo = results of search
   foundFoo = true if a valid foo has been found  

   return foo if foundFoo else someErrorCode

How can I accomplish this in C++?

Edited to remove numerous inaccuracies.

Upvotes: 10

Views: 21611

Answers (8)

stonemetal
stonemetal

Reputation: 6208

Is not finding a foo really an exceptional situation? Then throw an exception. Expect to not find foo? have the function return an error code and pass the foo out via a reference parameter, where foo is only valid if the function returns no error.

Upvotes: 0

zildjohn01
zildjohn01

Reputation: 11515

It's not possible in C++ without resorting to pointers or a library solution outside the standard library. (Boost is not a part of the standard library, it's a 3rd party solution.)

In C#, you can use a Nullable<Foo>.

Contrary to Billy's comment, structs are value types, not reference types, and Nullable can be applied to any value type, not just built-ins. The following compiles just fine:

struct Test {
    int Blah;
}
void Main() {
    System.Nullable<Test> proof;
}

Upvotes: 0

fredoverflow
fredoverflow

Reputation: 263158

You can look into boost::optional and see if it fits your needs. However:

return foo if foundFoo else someErrorCode

This makes me think that you might be better off throwing an exception if you don't find foo.

Upvotes: 3

Ruben Bartelink
Ruben Bartelink

Reputation: 61815

You cant do this in C# either - you would need to return new Foo(), not null to make the compiler happy.

Ditto the C++ case - you need to instantiate a struct if you're going to return by value. If not, you want to return by pointer (in which case you'd be newing or returning a pointer to one allocated in another manner, which brings messy ownership transfer semantics into the equation).

EDIT: Based on your update. It seems you want to return either a value or a 'null' meta-value that indicates 'not found'. You can do this in a number of ways:

  1. throw if it fails, otherwise unconditionally return a value
  2. return a pointer - but this leaves the responsibility for deleting it up in the air if it's not something that's going to stay in memory long term
  3. wrap it in a [templated] wrapper object that handles the conditionality in the same way that .NET's Nullable<T> would (I'll let someone chime in with the right one UPDATE: @Mike Seymour says it's boost::optional<foo>)
  4. use the Null Object pattern to return an appropriate value which does the right thing when treated as a valid resut on the client side

Upvotes: -1

Puppy
Puppy

Reputation: 146940

Throw an exception. That's what they're for.

Upvotes: 3

Justin Ardini
Justin Ardini

Reputation: 9866

One way of doing it is to return a pointer to a foo:

public Foo* findFoo()
{
    return fooFound ? new fooResult() : NULL;
}

Another possibility to define a NullFoo of some kind, possibly as a struct extending Foo with an empty implementation. For more information about the latter idea, you can read about the Null Object Pattern.

Edit: The modified question is somewhat different, and as other people have mentioned, you may be best off throwing an exception rather than doing either of the above.

Upvotes: 2

GManNickG
GManNickG

Reputation: 503983

C++ objects can never be null or empty. Pointers can hold a null pointer value indicating they point at nothing.

The typical solution would be to throw an exception. Otherwise, use a pointer; just make sure you aren't returning the address of a temporary.

I wouldn't recommend trying to teach yourself C++ with knowledge from other languages, you'll hurt yourself. Grab a good beginner-level book, it's the best way to learn.

Upvotes: 14

Matthew Flaschen
Matthew Flaschen

Reputation: 284836

That doesn't work in C# either. You should return a pointer to Foo.

Upvotes: 0

Related Questions