I am writing a program in C++ and have a std::map<int,TH1D> that I would like to write to my TFile. I understand that it is possible to write “simple” STL containers such as std::vector<int>; however, I think the TH1D is complicating things. Thanks in advance for the help!
For further information, the runtime error given by my program (compiles just fine) is "Error in <TFile::WriteObjectAny>: The class requested (map<int,TH1D>) for the key name "name" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (map<int,TH1D>). No data will be written."
I can reproduce the error. Wrapping the map inside a class like the following do not help. Following the example in root/tutorial/tree/dictionary do not work either.
#include <map>
#include <memory>
#include <TH1D.h>
class myclass{
public:
std::map<int, std::unique_ptr<TH1D> > m;
};
After a quick look in the forum, there are recent posts regarding the function Generate Dictionary, and it seems to be intended for testing purposes.
Hi Alvaro! Thanks for the reply and the time you spent checking this out!
I thought about a TTree as well; it’s a good idea. However, I was curious how to generate the dictionary if I wanted to avoid the TTree for whatever reason (or some other alternative which would allow me to save a container [like a map] directly).
I tried to generate dictionary for the following class but it does work only if the data is saved into a TTree. If it is saved as object into a TFile, it can not be retrieved.
I’m not sure what the issue was before. I just got it to compile with no errors. However, I still get runtime errors. Essentially the code is:
#include<map>
#include "TFile.h"
#include "TH1D.h"
#include "TInterpreter.h"
int main()
{
TFile f("output.root");
map<int,TH1D> m;
/* fill the map */
gInterpreter->GenerateDictionary("map<int,TH1D>", "map");
f.WriteObject(&m, "name");
return 0;
}
And the error I am getting is:
Warning in cling::IncrementalParser::CheckABICompatibility():
Possible C++ standard library mismatch, compiled with __GLIBCXX__ '20150623'
Extraction of runtime standard library version was: '20200408'
Error in <TFile::WriteObjectAny>: The class requested (map<int,TH1D>) for the key name "name" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (map<int,TH1D>). No data will be written.
The program finishes running after the error message and the exit code is 0
Edit:
I originally did not include this in the post, but since it may now be relevant: ROOT Version: 6.24/08 Platform: Linux x86_64 Compiler: c++ (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2)
Is the issue that I am using c++14 instead of c++11? My program uses features from the c++14 standard and I don’t have permissions to reinstall ROOT on the machine I am compiling and running the code on. Does this mean I am out of luck?
As a general rule, you need to compile your C++ programs using the same C++ standard version that was used to build the ROOT installation on your system (root-config --cflags | grep std).