The following files reproduces the error we are getting:
classes.h
#include <memory>
#include <iostream>
struct PdfInfo {
std::pair<int, int> id;
std::pair<double, double> x;
std::pair<double, double> xPDF;
double scalePDF;
};
class LHEEventProduct {
public:
typedef PdfInfo PDF;
class const_iterator {
public:
typedef std::forward_iterator_tag iterator_category;
typedef std::string value_type;
typedef std::ptrdiff_t difference_type;
typedef std::string *pointer;
typedef std::string &reference;
const_iterator() : line(npos) {}
~const_iterator() {}
inline bool operator == (const const_iterator &other) const
{ return line == other.line; }
inline bool operator != (const const_iterator &other) const
{ return !operator == (other); }
inline const_iterator &operator ++ ()
{ next(); return *this; }
inline const_iterator operator ++ (int dummy)
{ const_iterator orig = *this; next(); return orig; }
const std::string &operator * () const { return tmp; }
const std::string *operator -> () const { return &tmp; }
private:
friend class LHEEventProduct;
void next();
const LHEEventProduct *event;
unsigned int line;
std::string tmp;
static const unsigned int npos = 99999;
};
const_iterator begin() const;
inline const_iterator end() const { return const_iterator(); }
std::unique_ptr<PDF> pdf_;
};
classes_def.xml
<rootdict>
<class name="gen::PdfInfo" />
<class name="LHEEventProduct" />
</rootdict>
test.C
#include "classes.h"
auto filename = "out.root";
//auto filename = "out.xml"; // Change to this one to produce an xml output file and easily read it
void checkClassDictionaries(std::vector<std::string>& missingDictionaries,
std::type_info const& typeinfo) {
TClass* tClass = TClass::GetClass(typeinfo);
bool result = true;
THashTable hashTable;
bool recursive = true;
tClass->GetMissingDictionaries(hashTable, recursive);
for(auto const& item : hashTable) {
TClass const* cl = static_cast<TClass const*>(item);
std::cout << "missing dictionary for " << cl->GetName() << "\n";
missingDictionaries.emplace_back(cl->GetName());
result = false;
}
return result;
}
void printGenInfoProduct(const LHEEventProduct &g)
{
auto &id = g.pdf_->id;
auto &x = g.pdf_->x;
auto &xPDF = g.pdf_->xPDF;
auto &scalePDF = g.pdf_->scalePDF;
std::cout << "id = (" << id.first << ", " << id.second << ")\n"
<< "x = (" << x.first << ", " << x.second << ")\n"
<< "xPDF = (" << xPDF.first << ", " << xPDF.second << ")\n"
<< "scalePDF = " << scalePDF << '\n';
}
void write()
{
std::unique_ptr<TFile> f (TFile::Open(filename, "RECREATE"));
LHEEventProduct myGenEventInfoProduct;
// For the sake of this example
myGenEventInfoProduct.pdf_.reset(new PdfInfo());
myGenEventInfoProduct.pdf_->id = std::make_pair(2,3);
myGenEventInfoProduct.pdf_->x = std::make_pair(2.,3.);
myGenEventInfoProduct.pdf_->xPDF = std::make_pair(4.,6.);
myGenEventInfoProduct.pdf_->scalePDF = 42.;
std::cout << "Writing \n";
printGenInfoProduct(myGenEventInfoProduct);
f->WriteObject(&myGenEventInfoProduct, "myGenEventInfoProduct");
f->Close();
}
void read()
{
std::unique_ptr<TFile> f (TFile::Open("out.root"));
LHEEventProduct *myGenEventInfoProductPtr;
f->GetObject("myGenEventInfoProduct", myGenEventInfoProductPtr);
std::vector<std::string> missingDicts;
checkClassDictionaries(missingDicts, typeid(*myGenEventInfoProductPtr));
std::cout << "Reading \n";
printGenInfoProduct(*myGenEventInfoProductPtr);
f->Close();
}
void test()
{
write();
read();
}
output
root test.C
------------------------------------------------------------
| Welcome to ROOT 6.12/07 http://root.cern.ch |
| (c) 1995-2017, The ROOT Team |
| Built for linuxx8664gcc |
| From tag , 9 February 2018 |
| Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
------------------------------------------------------------
root [0]
Processing test.C...
Writing
id = (2, 3)
x = (2, 3)
xPDF = (4, 6)
scalePDF = 42
Error in <TStreamerInfo::Build>: LHEEventProduct: PdfInfo has no streamer or dictionary, data member pdf_ will not be saved
missing dictionary for __uniq_ptr_impl<PdfInfo,default_delete<PdfInfo> >
missing dictionary for LHEEventProduct
missing dictionary for PdfInfo
missing dictionary for unique_ptr<PdfInfo,default_delete<PdfInfo> >
missing dictionary for tuple<PdfInfo*,default_delete<PdfInfo> >
missing dictionary for default_delete<PdfInfo>
Reading
id = (2, 3)
x = (2, 3)
xPDF = (4, 6)
scalePDF = 42