Hello,
For some reason, I am not able to (de)serialize templated classes in ROOT. Pretty much identical code works fine for a regular class, but converted into a template, it either produces incorrect results or crashes ROOT altogether
Could you please help me to understand what I am doing incorrectly?
Here is a working example:
// File: TestClass.h
#ifndef TEST_CLASS_H
#define TEST_CLASS_H
#include "Rtypes.h"
#include <map>
#include <set>
/******************************************************************************/
class TestClass
{
public:
Int_t x;
int y;
using Map1 = std::map<int, double>;
Map1 map1;
using Set2 = std::set<double>;
using Map2 = std::map<int, Set2>;
Map2 map2;
ClassDef(TestClass,1)
};
/******************************************************************************/
#if !defined(__CLING__)
ClassImp(TestClass);
#endif
#ifdef __ROOTCLING__
#pragma link C++ class TestClass;
#endif
#endif
// File: test.C
// root.exe -b -l -q test.C+
#include "TestClass.h"
#include "TFile.h"
#include <iostream>
using std::cout;
using std::endl;
/******************************************************************************/
#if defined(__ACLIC__)
int test(void)
#else
int main(void)
#endif
{
// create object
TestClass tc;
tc.x = 888;
tc.y = 777;
tc.map1.insert( TestClass::Map1::value_type(111, 222.2) );
TestClass::Set2 s2; s2.insert(333.3); s2.insert(555.5);
tc.map2.insert( TestClass::Map2::value_type(444, s2) );
const char * const fileName = "test.root";
// write object
TFile oFile(fileName, "RECREATE");
oFile.WriteObject(&tc, "tc");
oFile.Close();
// read object
TFile iFile(fileName, "READ");
TestClass * tc2 = (TestClass*) iFile.Get("tc");
cout<<"tc2->x = "<<tc2->x<<endl;
cout<<"tc2->y = "<<tc2->y<<endl;
cout<<"tc2->map1[111] = "<<tc2->map1[111]<<endl;
cout<<"tc2->map2[444] = "<<*tc2->map2[444].begin()<<endl;
cout<<"tc2->map2[444] = "<<*tc2->map2[444].rbegin()<<endl;
iFile.Close();
delete tc2;
return 0;
}// end of function
/******************************************************************************/
Here is a not working template example:
// File: TestClassT.h
#ifndef TEST_CLASS_H
#define TEST_CLASS_H
#include "Rtypes.h"
#include <map>
#include <set>
/******************************************************************************/
template <class T>
class TestClassT
{
public:
TestClassT(void) {}
Int_t x;
T y;
using Map1 = std::map<T, double>;
Map1 map1;
using Set2 = std::set<double>;
using Map2 = std::map<T, Set2>;
Map2 map2;
ClassDef(TestClassT,1)
};
/******************************************************************************/
#if !defined(__CLING__)
ClassImp(TestClassT<int>);
//templateClassImp(TestClassT);
#endif
#ifdef __ROOTCLING__
#pragma link C++ class TestClassT<int>;
#endif
#endif
// File: testT.C
// root.exe -b -l -q testT.C+
#include "TestClassT.h"
#include "TFile.h"
#include <iostream>
using std::cout;
using std::endl;
/******************************************************************************/
#if defined(__ACLIC__)
int testT(void)
#else
int main(void)
#endif
{
// create object
using TestClass = TestClassT<int>;
TestClass tc;
tc.x = 888;
tc.y = 777;
tc.map1.insert( TestClass::Map1::value_type(111, 222.2) );
TestClass::Set2 s2; s2.insert(333.3); s2.insert(555.5);
tc.map2.insert( TestClass::Map2::value_type(444, s2) );
const char * const fileName = "testT.root";
// write object
TFile oFile(fileName, "RECREATE");
oFile.WriteObject(&tc, "tc");
oFile.Close();
// read object
TFile iFile(fileName, "READ");
TestClass * tc2 = (TestClass*) iFile.Get("tc");
cout<<"tc2->x = "<<tc2->x<<endl;
cout<<"tc2->y = "<<tc2->y<<endl;
cout<<"tc2->map1[111] = "<<tc2->map1[111]<<endl;
//cout<<"tc2->map2[444] = "<<*tc2->map2[444].begin()<<endl; // XXX: if this code is added, ROOT crashes
//cout<<"tc2->map2[444] = "<<*tc2->map2[444].rbegin()<<endl; // XXX: if this code is added, ROOT crashes
iFile.Close();
delete tc2;
return 0;
}// end of function
/******************************************************************************/
The working example output:
The template example output:
If the two lines marked with XXX are added to the 2nd example, I get (a lot of errors and) [quote]Segmentation fault (core dumped)[/quote]
Could you please let me know what I am doing wrong with (de)serialization of templates in ROOT?
ROOT version: 6.06.04
Thank you very much for your help,
Siarhei.