George A. Heintzelman writes: > > Be aware that CINT does not really support template members, so much of > your template machinery will have to be hidden from CINT in order for > it to work at the command line. (Either that or you'll have to talk to > Masaharu Goto personally to figure out how to implement what you need. > ;) Yes, I have learned that templates from CINT are tricky. I anticipated having to put lines like: #pragma link C++ class RegistryItemXxx<int>; #pragma link C++ class RegistryItemXxx<double>; #pragma link C++ class RegistryItemXxx<TObject>; in my LinkDef.h file in order to let CINT know about the specializations that will be needed. Although, the main use of this container is in pre-compiled code. > Basically, you need to figure out what interface you want to use to the > ROOT streamers for the registry items. Personally, I would probably do > it something like this: > > In Registry::Streamer, loop over the map writing out the key (either as > a root TString or with your own TBuffer & operator<<(const std::string > &) ), the value type (from a virtual RegistryItem function call). and > the value. The value you write out with a virtual function call in > RegistryItem, which you will have to specialize for types which are not > ROOT TObjects. > > The tricky part will be deciding how to tell the write out what > absolute type it is. Unfortunately, you can't portably use the > type_info::name() function since it is implementation-defined, which is Life would be a whole lot easier if type_info::name() was guaranteed to be same on all compilers. This just seem too useful, does any one know why this was not put in the C++ standard? One way to solve this problem would be to write a compiler specific wrapper function to reformat the output of type_info::name() into some canonical format. This was done in the implementation used for: http://www.mathcs.sjsu.edu/faculty/pearce/patterns.html. He used djgpp and VC++ which aparently had relatively simple class name encodings. I have looked at what kind of names G++ produces, and they are in general not so simple. > precisely why the ROOT guys use their ClassName() and such the way they > do. If you want to write out ROOT objects, you're set -- just use the > class's ClassName function. For other classes, you probably ought to > write a specialization of RegistryItemXxx<T>::Name. For read in, you > supply a registry of RegistryItemXxx<T>::Name which can look up a > static function returning a T* for the relevant classname string. Thank you for this good advice, I think I even understand it. As for handling non-ROOT types, I guess I can safely restrict all non-TObject types to only the few basic C++ types (int, double, etc) and hand code specialized constructors which instead of saving the raw value to fData, first wraps the raw value in a TObject based class. There is still the issue of catching the error when someone tries to pass a non-base or TObject derived type. > You DO realize you're basically redoing ROOT-io in the way it would > probably have been done had the ROOT guys been able to portably use > template machinery when they first wrote it, right? <gulp> That is sobering. Am I doing a good thing or a foolish thing? > > // The container > > class Registry > > { > > public: > > // non-templated ctor/dtor > > > > // templated accessors > > template<class T> T GetVal(string key); > > template<class T> void SetVal(string key, T value); > > This of course should be SetVal(string key, const T & value), right? > You don't want to make more copies than you must (and you must make one > when you create your RegistryItemXXX). Oops, yes, it should be (but wasn't). And yes, I do ``new'' a copy for storing in the RegistryItemXxx<T>. Thanks. -Brett.
This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:35 MET