Error in <TBranchElement::InitializeOffsets>: Could not find the real data member '_M_elems[5]' when constructing the branch 'a' [Likely missing ShowMember].
The reproducer is a simplified version of a general-purpose code that creates a branch by querying the class name at runtime, which ideally should work for any kind of class, and which gives the above error when used with a std::array.
By replacing the Branch call with:
t->Branch("a", &a);
the error vanishes, the actual branch type becomes float[5], and everything works as expected even when reading the branch out using a std::array buffer. Unfortunately I cannot use this template overload since the object type has to be determined at run time in the real general-purpose code.
So my question is: is it possible to obtain the correct behavior using an overload of Branch that determines the type at run time?
The syntax you use is not yet implemented for std::array, in the meantime you need a work-around. You need to transform the string "array<float,5ul>" into "somename[5]/F"
Thanks for the tip, Philippe. In another thread you mentioned that there are other types (i.e. std::pair, std::tuple, std::unique_ptr) that features a special treatment regarding I/O, if I correctly understood your comment. Is there any reference about how to treat them in this context? I guess I can reverse-engineer it but documentation would be preferable.
std::pair and std::ntuple are special in that their dictionary is generated implicitly. When creating branches there is nothing different/unusual to do.
std::unique_ptr is special is that it is treated by the I/O (in most cases) as a raw pointer. The impact on using std::unique_ptr vs a raw pointer are the same, the lifetime of the pointer variable needs to be longer than the lifetime of the tree.
@pcanal One last question related to this topic: if I’m correct there’s no way at the moment to create a branch holding a std::array<SomeClass,N>, right? If I try like this:
std::array<TH1F,5> ah;
t.Branch("b", &ah);
I get this:
Error in <TTree::Branch>: std::array of objects not yet supported as top level branch object (the class is array<TH1F,5>)
Is there any plan to support this case in future releases? I’m using 6.26/04.
We are unlikely to add it as we are focusing development effort on RNTuple. Note that you can use std::vector<TH1F> (albeit it is less storage efficient) or wrap the array in a struct for which you generate the dictionary.