Dear Root experts,
I have the following problem: I have a class that load a TChain and then loop on the entries executing a function for every entry; the function has a defined signature and is a private non-static member of the class.
Since I have many of these functions, I thought of doing an array of pointer to member functions and using an enumeration to index the function I want to be used.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <TMath.h>
#include <TString.h>
#include <TChain.h>
#include <TFile.h>
using namespace std;
class DataSet;
typedef bool (DataSet::* SelectionFunc)();
class DataSet
{
public:
// Event
UInt_t RunID; // Run number
UInt_t EventID; // Event number
enum selections_t
{
SEL1,
nSELECTIONs
};
SelectionFunc Selections[nSELECTIONs];
DataSet(const Char_t *filename, const Char_t *treename) : chain(NULL)
{
initialize_selections_ptrs();
load_chain(filename, treename);
}
~DataSet()
{
if (chain != NULL) delete chain;
}
bool CreateEventList(UInt_t selection, Char_t *filename)
{
Long64_t selected = 0;
ofstream file;
file.open(filename);
if (file.is_open())
{
for (Long64_t ientry = 0; ientry < entries; ++ientry)
{
chain->GetEntry(ientry);
if ((this->*Selections[selection])(this))
{
++selected;
file << RunID << " " << EventID << endl;
}
}
file.close();
cout << Form("Selected %lld events (%g%%)\n", selected, (Double_t)selected/entries*100.);
return true;
}
else
{
cout << Form("Error in opening file: %s\n", filename);
return false;
}
}
TChain *chain;
Long64_t entries;
private:
bool sel1();
void initialize_selections_ptrs()
{
SelectionFunc selections[nSELECTIONs] = {
&DataSet::sel1
};
for (UInt_t iselection = 0; iselection < nSELECTIONs; ++iselection)
Selections[iselection] = selections[iselection];
}
void load_chain(const Char_t *filename, const Char_t *treename)
{
chain = new TChain(treename);
chain->Add(filename);
entries = chain->GetEntries();
cout << Form("Loaded '%s:/%s': %lld entries\n", filename, treename, entries);
chain->SetBranchAddress("RunID", &RunID);
chain->SetBranchAddress("EventID", &EventID);
}
};
bool DataSet::sel1()
{
return true;
}
It doesn’t work: if I try to compile it (.L DataSet.C+), cint says
DataSet_C_ACLiC_dict.cxx:138: error: declaration of ‘Selections’ as array of void
DataSet_C_ACLiC_dict.cxx: In function ‘void ROOT::DataSet_ShowMembers(void*, TMemberInspector&)’:
DataSet_C_ACLiC_dict.cxx:279: error: ‘class ROOT::Shadow::DataSet’ has no member named ‘Selections’
To make it work, I had to declare the functions external to the class and pass them a pointer to the instance of DataSet, but in this way I cannot use private members.
Am I using pointer to member function in the wrong way?