Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What function signature should I use to return a reference to an object that might not exist?

I'm writing a simple container class in C++ similar to a map that stores objects indexed by a key. I'd like to provide an accessor function such as:

V& getValue(const K &key);

where I return a reference to the value.

But I also wanted to handle the case where the key/value is not present and be able to return some status to the user (there could be some reasons why it is not there that I want to communicate back to the caller via some Status type).

I suppose I could do the following but calling this would require a V object to be constructed before this function can be called, and I'm just going to copy the internal V object into the one being passed in by reference, so that seems bad.

Status getValue(const K &key, V& v);

I could also do:

V &getValue(const K &key, Status &s);

But for some reason that seems a little bit clunky as focus is drawn away from the Status and users may forget to check it (but maybe that's not my problem).

So is there anyway to have a function similar to

Status getValue(const K &key, V& v);

without the a dummy V object needing to be constructed before calling it? You can't pass a reference to a reference. I suppose I could use pointers and am happy to do so, but it is less desirable for creating a simple to use and reason about function.

Any thoughts?

like image 653
innocent_bystander Avatar asked Aug 15 '12 14:08

innocent_bystander


2 Answers

The usual solution is to provide a bool contains(const K &key) function and if you don't want your accessor to silently create entries, have it throw an exception instead. (having two accessors, one that throws an exception, and another that creates entries is also common)

Of course, this may not be what you want. What is the reason you want to fit all this into a single function?

like image 183
AI0867 Avatar answered Oct 27 '22 07:10

AI0867


You could go with your original function V& getValue(const K &key), and throw an exception to indicate non-successful Status values.

Then, callers have the option of delaying how they handle the problem (by letting the exception bubble up to an appropriate handler), but they cannot outright forget about it because the program will crash otherwise. The call site needn't be cluttered with status-checking and error-reporting code.

like image 39
Rob Kennedy Avatar answered Oct 27 '22 07:10

Rob Kennedy