Template with rootcint

Hello,

I have some problems with root.
Here’s my code:

Device.h

template < class T >
class Device
{
public:
	typedef T Element;
	typedef std::vector<Element> SubElement;
   ClassDefT(Device,1);
}

I need to declare Device<Device<Device > >
Channel is a class added to root ( no problem).

LinkDef.h

#ifdef __CINT__

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;

#pragma link C++ nestedclass;
#pragma link C++ nestedtypedef;

#pragma link C++ class Detector+;

#pragma link C++ class DreamDetector+;

#pragma link C++ class Channel;
#pragma link C++ class Device< Channel>;
#pragma link C++ class Device< Device<Channel> >;
#pragma link C++ class Device< Device< Device<Channel> > >;

#endif

but while compiling, i’ve some error about streamer for Device<Device > and Device<Device<Device > > :

Dict.cpp: In member function 'void Device<T>::Streamer(TBuffer&) [with T = Device<Channel>]'
Dict.cpp:787: erreur: no matching function for call 'std::vector<Device<Channel>, std::allocator<Device<Channel> > >::push_back(Channel&)'
vector.h:686: note: candidat sont: void std::vector<_Tp, _Alloc>::pushback(const _Tp&) [with _Tp = Device<Device<Channel> >, _Alloc = std::allocator<Device<Device<Channel> > >

And the same lines for Device<Device >
and finally:

Dict.cpp: At global scope: Dict.cpp:915: erreur: specialization of 'void Device<T>::ShowMembers(TMemberInspector&, char*) [with T = Device<Device<Channel> >]' after instanciation make: *** Dict.o erreur 1

Can you help me?

Hi,

I start pointing out a piece of documentation you might find useful:
You can take a look at root.cern.ch/root/html534/guides … aClass.pdf for more

Unfortunately, the snippet for your class cannot work as it is: you are missing the vector header for example as well as the Channel class. I took the freedom to simplify your example to get you started.
Now, to proceed with the dictionary generation:
The header file

class Channel{};

template < class T >
class Device{};

namespace {
Device< Channel> i_1;
Device< Device<Channel> > i_2;
Device< Device< Device<Channel> > > i_3;
}

Notice the absence of ClassDef (your class does not inherit from TObject) and the template instantiations which are necessary to produce dictionaries for templates.
The linkdef file

#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;

#pragma link C++ class Channel+;
#pragma link C++ class Device< Channel>+;
#pragma link C++ class Device< Device<Channel> >+;
#pragma link C++ class Device< Device< Device<Channel> > >+;
#endif

Notice the “+”.

The rootcint invocation and the compilation

rootcint  -f classes_dict.cxx -c classes.h  linkdef.h
clang++ -o libA.so -shared -fPIC classes_dict.cxx `root-config --cflags` 

You are now able to load the library within your interpreter and use the selected classes as well to do I/O with them.

Cheers,
Danilo

Hi,

as a side note: I might have been too aggressive in stripping down your code for producing the example.
Indeed you can profit from the presence of ClassDef in your classes even if they don’t inherit from TObject: root.cern.ch/drupal/content/addi … assdef#why

Cheers,
Danilo


#pragma link C++ class Channel+;
#pragma link C++ class std::vector+;
#pragma link C++ class Device< Channel>+;