Re: hasMember
Andrea Crotti <andrea.crotti.0@gmail.com> wrote in
news:m11v5rrcno.fsf@ip1-201.halifax.rwth-aachen.de:
Jeff Flinn <TriumphSprint2000@hotmail.com> writes:
To avoid the memory allocation and ownership issues use
boost::optional.
#include <boost/optional.hpp>
typedef boost::optional<int> optional_int;
optional_int Cont::getValue(int idx) const
{
std::map<int, int>::const_iterator itr = content.find(idx);
return (itr != cont.end())? itr->second : optional_int();
}
and:
if(optional_int i = obj.getValue(idx)) // safe bool idiom
{
int x = *i + 123; // deref for value
}
Using exceptions in this case could be good?
Seems out of place for the use you've described, given what little
info you've provided.
Jeff
Interesting the optional_int, but I can't use boost...
I'm sure boost::optional is quite easy (and instructive) to implement by
yourself.
Anyway I didn't specify much because is a general (for me) problem,
every time I have a class which has some structure (set/vector/map) I
might want to check and get some values from it.
This might reflect a deeper design problem. A class is meant for
encapsulating some bunch of data together with functions operating on
this data. From your description it sounds like trying to tear this
encapsulation apart.
So returning -1 or NULL is for me not nice, using exceptions I meant
something like done in std::vector::at for example
try {
int x = vec.at(0);
} catch ...
I could throw an exception whenever I don't find the value and catch it
in the caller, that's what I meant..
Exceptions are meant more for propagating errors multiple layers up the
call stack. If the not-found event is common and expected, then it is not
"exceptional" and should not be expressed as an exception. Besides, the
exception mechanism may easily be much slower than searching the
container twice (which was your original worry).
Have you considered the simple way of having another output parameter in
addition to the return value?
bool Cont::getValue(int idx, int& value_out) const
{
std::map<int, int>::const_iterator itr = content.find(idx);
if (itr != content.end()) {
value_out = itr->second;
return true;
} else {
return false;
}
}
// ...
int x;
if (obj.getValue(idx, x)) {
// x found and valid, do something with x
}
This has the drawback that the lexical scope of x is too broad, but if
this is a very low-level class used only by a couple of slightly higher-
level classes this might be OK.
hth
Paavo