Templates: generic "return null;"
TheFlyingFiddle
theflyingfiddle at gmail.com
Mon Feb 3 16:43:52 PST 2014
On Monday, 3 February 2014 at 10:25:19 UTC, Chris wrote:
> Is there a way I can make the return type in getAttribute
> generic? null does not work with numbers.
>
> MyStruct(T) {
> T[T] attributes;
> // ....
> public auto getAttribute(T attr) {
> if (!(attr in attributes)) {
> return null; // Doesn't work for numbers!
> }
> return attributes[attr];
> }
> }
>
> void main() {
> auto myStr = MyStruct!int(0); // Error
> }
Whenever i am faced with this situation i do one (or more then
one) of the following things.
struct MyStruct(T)
{
T[T] attributes;
//(1) Forward the underlying access method Eg:
auto opBinaryRight(string s : "in")(T attrib)
{
return attrib in attributes;
}
//(2) make a try method.
bool tryAttrib(T attrib, out T outAttrib)
{
auto p = attrib in attributes;
if(p) outAttrib = *p;
return p !is null;
}
//(3) Give user option to set default value.
T attribOrDefault(T attrib, T default)
{
auto p = attrib im attributes;
return p is null ? default : attrib;
}
//(4) Use Nullable!T (I prefer #5 over this one)
Nullable!T attribOrNull(T attrib)
{
Nullable!T result;
auto p = attrib ib attributes;
if(p) result = *p;
return result;
}
//(5) Use a pointer but not forward in operator.
T* attribPtr(T attrib)
{
return attrib in attributes;
}
//(6) Throw exception (I only do this in combination with one
of the above)
T attribEx(T attrib)
{
return *enforce!AttribNotFoundEx(attrib in attributes);
}
}
My personal preference using #2 and #3 in combination. #2 covers
the basic case "Is this thing avalible?" and #3 covers the case
"Give it to me if it is avalible or use this default value" I
think it gives a clear image of what your code is doing at the
callsite. Only using #2 or #3 limits you in this sence.
For #1, #4 and #5 i personally stay away from them. They force
the caller to either use an if or potentially trigger a null
pointer derecerence. (Btw what is the benefit of #4? I have never
used it since it seems pointless)
I very rarly use attribEx. I don't think code shuld just spew
exceptions all over the place. They should be reserved for really
bad stuff, like bounds checks. One exception i make to this rule
is if i'm dealing with ranges. Since the other methods don't lend
themselfs for UFCS-chaing.
More information about the Digitalmars-d-learn
mailing list