Hi,
I have written analysis package so that boiler plate things common to different
analyses happen in one class, and user would write a subclass that would be specific to each analysis. The RDataFrame object is instantiated in the superclass, and many Defines are made there. I wanted the writer of the subclass not access RDF object directly, but through a method in the superclass, shown below. I honestly don’t know templates well, so I don’t know if it’s even correct.
template <typename T, typename std::enable_if<!std::is_convertible<T, std::string>::value, int>::type = 0>
void NanoAODAnalyzerrdframe::defineVar(std::string varname, T function, const RDFDetail::ColumnNames_t &columns)
{
_rlm = _rlm.Define(varname, function, columns);
}
It compiles fine, but fails during linking when I make a call like
defineVar("sphericityQ", ::sphericity , {"cleanjet4vecs"});
undefined reference to `void NanoAODAnalyzerrdframe::defineVar<ROOT::VecOps::RVec<float> (*)(std::vector<ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >, std::allocator<ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> > > >&), 0>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, ROOT::VecOps::RVec<float> (*)(std::vector<ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >, std::allocator<ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> > > >&), std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)'
collect2: error: ld returned 1 exit status
How should I change the method?
If I make _rlm, the RDF object, public, it works as expected, but would like to avoid accessing it directly.
_rlm = _rlm.Define("sphericityQ", ::sphericity , {"cleanjet4vecs"});
Regards,
Suyong
_ROOT Version: 6.15/01
_Platform: Linux
_Compiler: 6.4.1