How to generate a dictionary of std::vector<TVector3> when compiling my code

Dear experts

I was trying to extract some TTree branch contains std::vector<TVector3> type values, I know I can write a macro and add a line: #pragma link C++ class std::vector<TVector3>+; and do something like: root macro.cxx++ to make it work.
But I want to compile my code by c++ compiler, which means it starts from int main(int argc, char** argv) instead of some function. How can I make it work instead of getting this error:

Error in <TTree::SetBranchAddress>: The class requested (vector<TVector3>) for the branch "trkDir" is an instance of an stl collection and does not have a compiled CollectionProxy. 
Please generate the dictionary for this collection (vector<TVector3>) to avoid to write corrupted data.

Hi,

The instructions can be found here I/O of custom classes - ROOT .

Cheers,
D

Thank you for your reply, but I don’t have any custom classes in my code, I just want to use std::vector where std::vector is a STL class and TVector3 is a ROOT class both are already implemented, how can I use the combination of them?

Hi,

Since the dictionary for that class is not already present in ROOT, it counts as a custom class: the documentation above is relevant in this respect.
Starting from the next ROOT releases, thanks to your post, the dictionary for the vector<TVector3> will be available natively ([math] Add dictionary for vector<TVector3> by dpiparo · Pull Request #15669 · root-project/root · GitHub)

Cheers,
D

Hi,

While waiting for the next release, here you may find a minimal working code that shows what you want to do.

Best,
Alvaro

Thank you for the information! I think the point is I don’t know what should I write in the std::vector<TVector3> cxx file and hxx file… normal custom TObject class has there own definitions, but what should I write in a std::vector<TVector3> class?
I mean, I need to give a name of the custom class at first, right? like:

class custom : public TVector3, public std::vector<TVector3>
{
};

Hi,

The example I linked does not need inheritance.

After defining your own custom class (in files .h, .cxx), use pragmas to make the dictionary for the class and possible containers, as in the example. If you want to use a vector of TVector3, I think it is enough to add the corresponding pragma in the file LinkDef.h,

#pragma link C++ class std::vector<TVector3>+;

If TVector3 is a class of ROOT, in order to make the dictionary maybe it is enough to include the header and link against the corresponding root shared library wherever the definition of that class is.

But how to define my class aka. std::vector …? I don’t know what should I write in the class file, what I need is only the variable type of std::vector<TVector3> where std::vector and TVector3 are already defined in STL and ROOT

I followed the page you shared and tried to generate dictionary:

  1. write LinkDef.h:
#ifdef __CLING__
#pragma link C++ class std::vector<TVector3>+;
#endif
  1. use rootcling to generate dictionary:
    rootcling -f Dict.cxx LinkDef.h

But I got error:
Warning: Unused class rule: std::vector<TVector3>

Hi,

I think you are forgetting the appropriate headers.
Have you read I/O of custom classes - ROOT ?

Cheers,
D

Yes I have read the page you shared, the header files in my case do you mean TVector3.h or both TVector3.h and std::vector.h?

Ah, after I add TVector3.h in my rootcling command it worked.

May I ask another question that what is the meaning of the plus sign “+” in the LinkDef.h?
#pragma link C++ class std::vector<TVector3>+;

Hi,

Excellent: thanks for sharing.
The + after the class name enables extra features and performance improvements in the I/O of the type (for more details, see here.

Cheers,
Danilo