epics-base / pvDataCPP

pvDataCPP is an EPICS V4 C++ module
https://epics-base.github.io/pvDataCPP/
Other
6 stars 16 forks source link

Add PVStructure::getAs<>() #4

Closed mdavidsaver closed 9 years ago

mdavidsaver commented 9 years ago

Access to sub-fields of a structure with exceptions thrown if this is not possible. Addresses #2.

Replaces findSubField() with private method PVStructure::GetAsImpl(), which uses char* instead of std::string to avoid temporary allocations. Loops instead of recursing. Also, uses exception messages to give some hint about why the lookup fails.

gregoryraymondwhite commented 9 years ago

Isn't the utility of getting as type (getAs<>) orthogonal to the question of whether you want the get to throw exception. You need a checked and an unchecked version - the second one just returns a null to indicate that the field wasn't present. As a user one would use the second one in the case of optional fields.

dhickin commented 9 years ago

Greg's absolutely right, these question of exception policy and return type are completely orthogonal.

Having two functions which differ by whether they return null pointers or throw is entirely reasonable, just as vector has checked and unchecked index operators, and I completely see the usefulness of exceptions in chaining.

However it's been a long standing design decision to use shared pointers in EPICS V4. I think this has been worked well and is certainly safer. Returning a reference instead of a pointer is completely unnecessary and unrelated to the issues of exceptions. Chaining is equally possible with shared pointers. The API now becomes more confusing as we mix "."s ans "->"s

If we keep these checked methods I would prefer them to return a shared_pointer.

One alternative would be to roll our own shared pointer, using the existing version as a base, which throws exceptions when operator* and operator-> are called with the pointer null. This would allow us to keep all client code as is, including accessing optional methods. It allows chaining. It avoids the seg fault from null pointers. You can , if you want, do multiple gets or chains of gets inside a single try/catch without checking the pointers each-time, except for optional fields. It also brings it closer to the Java null pointer exception behaviour.

This would, however, require some work. Having checked and unchecked versions would be simpler.