According to https://sft.its.cern.ch/jira/browse/ROOT-8784ClassDefInline should make it possible to bypass the situation where “one of the template instances can not have its dictionary generated (for example some members are references) but other template instance needs to have their dictionary generated”.
I am trying to use ClassDefInline (in non-interactive mode) to avoid having to IO a template instance where the members are references, but I get that fgIsA cannot be found. Manually adding static atomic_TClass_ptr fgIsA; to my private data members solves this, but then I get a bunch of error: uninitialized reference member <reference_member> which I got using the normal ClassDef as well…
What I had done up til now to take care of reference members was to expand the ClassDef macro in my class’ header file, default initialize some of its functions, and delete the LinkDef entry of the reference template instance. This works fine, but is kind of ugly.
I had hoped `ClassDefInline`` would be a more elegant solution. So I hope someone could tell me how to use it.
I don’t see where the error message mentions fgIsA …
Right, that’s because I added it as a private data member myself. If I wouldn’t do that I would get:
/home/ahmad/biodynamo/build/bdmDict.cxx: In static member function ‘static TClass* bdm::CellExt<Base, TBiologyModuleVariant>::Dictionary() [with Base = bdm::SimulationObject<bdm::Soa>; TBiologyModuleVariant = mpark::variant<bdm::NullBiologyModule>]’:
/home/ahmad/biodynamo/build/bdmDict.cxx:1598:4: error: ‘fgIsA’ was not declared in this scope
fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::bdm::CellExt<bdm::SimulationObject<bdm::Soa>,mpark::variant<bdm::NullBiologyModule> >*)0x0)->GetClass();
Making the default constructor deleted creates a problem for the non-reference template instances. It leads to the following error:
/home/ahmad/root/include/Rtypes.h:230:28: error: call to deleted constructor of 'bdm::CellExt<bdm::SimulationObject<bdm::Soa>, mpark::variant<bdm::NullBiologyModule> >'
return p ? new(p) T[nElements] : new T[nElements]; }
Unfortunately the situation is a little more complicated to solve this problem with partial specialization (at least to my knowledge). The CellExt<T, Q> class takes for T one of the three predefined structs, of which one is defined as the following:
This is the template argument that is giving me the uninitialized reference members errors as show in the third post. The vec data members in CellExt will namely become references, which will not be initialized (and don’t need to be initialized) when ROOT creates the IO methods, hence the error messages.
But partial specialization (even if it would work) would seem like a less elegant way then to just do the ClassDef expansion I mentioned earlier. I had hoped ClassDefInline could just ignore the reference-containing struct as the template parameter argument when generating the IO methods.