ACLiC Pragmas to Access Templated Class & Members in CINT

Hi, I’m trying to figure out what #pragma directives I need to put into my code so that CINT can see some templated code.

In my code I have:

  • a non-templated class with templated static member functions.
  • a templated class with regular member functions.

The templates in question are all over integers: using foo, not foo. In the case of the templated class, it has two templated integer parameters: foo<unsigned int k, unsigned int N>. All the templates have some kind of specialization. The actual code is attached to this post.

I read through http://root.cern.ch/download/doc/ROOTUsersGuideHTML/ch15s05.html but it’s a complete mess. I can’t figure out which parts are about 8 year old versions of ROOT and which are still current. Nowhere does it mention how to let CINT know about a templated class except for templates over types like std::vector.

I tried a bunch of variations of the following lines at the bottom of MySpline.C:

#if defined(__MAKECINT__)
#pragma link C++ defined_in MySpline;
#pragma link C++ nestedclass;
#pragma link C++ class MySpline::MySpline;
#pragma link C++ function MySpline::MySpline::Poly<2>(const double * const, const double * const);

#pragma link C++ class MySpline::PieceWise<0,1>;
#pragma link C++ class MySpline::PieceWise<0,2>;
#pragma link C++ class MySpline::PieceWise<0,3>;
//#pragma link C++ class MySpline::PieceWise<unsigned int,unsigned int>(const double * const);
#endif[/code]

I couldn't get MySpline::MySpline::Poly<N> to work as a static method:
[code]
root [2] double x[] = {5}
root [3] double c[] = {1,2,3,4,5}
root [4] MySpline::MySpline::Poly<0>(x,c)
Error: > Illegal operator for pointer 3 (tmpfile):1:
(const int)0
*** Interpreter error recovered ***
[/code]
It only works if I actually instantiate a MySpline::MySpline:
[code]
root [5] MySpline::MySpline ms;
root [6] ms.Poly<0>(x,c)
(double)0.00000000000000000e+00
root [7] ms.Poly<1>(x,c)
(double)1.00000000000000000e+00
root [8] ms.Poly<2>(x,c)
(double)1.10000000000000000e+01
[/code]

My specific MySpline::PieceWise<0,N> do work properly, but if I try to put a non-zero N value it doesn't work.  I think it's because PieceWise<0,N> has a default constructor while PieceWise<k,N> does not have a default constructor because it stores its constructor arguments in a const vector.  I tried adding the last commented-out pragma with the constructor signature for PieceWise<k,N> but it gives this error when I try to load it:
[code]root [0] .L MySpline.C+
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/jfcaron/Projects/Proto2BeamTest2/code_test/./MySpline_C.so
Error: regular expression error MySpline.C:244:
Warning: Error occurred during reading source files
Warning: Error occurred during dictionary source generation
!!!Removing /Users/jfcaron/Projects/Proto2BeamTest2/code_test/MySpline_C_ACLiC_dict.cxx /Users/jfcaron/Projects/Proto2BeamTest2/code_test/MySpline_C_ACLiC_dict.h !!!
Error: /Users/jfcaron/Software/custom_root/compiled/bin/rootcint: error loading headers...
Error in <ACLiC>: Dictionary generation failed!

In the absence of good documentation about this, can an expert give solutions that will allow me to use MySpline::MySpline::Poly and MySpline::PieceWise<k,N> for pre-defined but arbitrary unsigned integers k and N?

If it’s the namespace that is messing things up, I’m willing to sacrifice that and put it in the global namespace.

Thanks,
Jean-François
MySpline.C (8.49 KB)