Use template class in ROOT environment

Hi,

I made a template class and I can compile it as
.L TProperty.cpp+

Now I am testing my class, I got the following errors:

Am I missing something?

Thanks.

gma

Hi,

You need to tell the dictionary generator which template instance to generate a dictionary for:#ifdef __MAKECINT__ #pragma link C++ class TProperty<std::string,Double_t>+; #endif

Cheers,
Philippe.

Hi,Philippe,
Many thanks. It works now. :smiley:

Now I just put your pragma into my class header file. In the user manual, it mentioned LinkDef.h. I am wondering how I use this file. Where should I put it? The folder where my class is or some default search path for ROOT? Do I need to name different LinkDef.h files for different classes? What if I want to compile my code and do I need to let g++ know the LinkDef.h file?

Would you mind elaborating this a bit? I don’t really understand this part in the manual. Thank you in advance.

regards,

gma

Hi,

You would need a linkdef file only if you are not using ACLiC. In that case you need to generate the dictionary file:rootcint -f mydict.cxx -c myheader.h mylinkdef.h
then then compile mydict.cxx and link it in your library (i.e. as any other source file in your Makefile.
The mylinkdef.h file is usually kept along side your header files.

[quote]Do I need to name different LinkDef.h files for different classes?
[/quote]Usually there is one linkdef file per library.

[quote] do I need to let g++ know the LinkDef.h file? [/quote]not directly.

Cheers,
Philippe.

Many thanks, Philippe.

Now I got some compilation errors coming from iterator. My error is

/home/gma/light/src/./TSimplePropertySet.cpp:53: error: expected constructor, destructor, or type conversion before ‘TSimplePropertySet’

My codes are

template <class N, class V>
TSimplePropertySet<N,V>::iterator TSimplePropertySet<N,V>::Begin()
{ 
	return sl.begin();
}

where

list<TProperty<N,V> > sl;

Is there any limitation in using STL iterator? Thanks.

regards,

gma

Hi,

The compiler does not seem to know TSimplePropertySet<N,V>::iterator.
What is the complete declaration of your class template TSimplePropertySet?

Cheers,
Philippe.

Phillipe,

Attached please find the code. I am still not sure where the error is. Constructor seems fine to me. Thank for your helps.

regards,

gma
file.tar (10 KB)

Hi,

You need to add typename in front of the use of the nested typedefs:[code]// Iterator functions
template <class N, class V>
typename TSimplePropertySet<N,V>::iterator TSimplePropertySet<N,V>::Begin()
{ // Return iterator at begin of composite

return sl.begin();

}[/code]

Cheers,
Philippe.

Hi, Phillipe,

Thanks. It works if I did not put those linkdef macros in my code. Otherwise. I got the following error message:

I did not use TString, so I don’t understand the message.
Attached please find new files. You may get better clue. Thanks.

regards,

gma
file.tar (20 KB)

Hi,

In template <class N, class V> void TSimplePropertySet<N,V>::remove(const N& value) { // Remove all elements with 'value' O(N) // We iterate over the list until we find the value iterator it; for (it=sl.begin(); it!=sl.end(); it++) { if ((*it)() == value) { sl.erase(it); } } }You are trying to compare an object of type ‘N’ (the variable value) to an object of type ‘V’ (the return value of (*it)(). I suspect you might have meant to have the following function instead:

template <class N, class V> void TSimplePropertySet<N,V>::remove(const V& value) ...

Cheers,
Philippe.

PS. The ‘odd’ error message is due the fact that one can construct TString object from both ‘double’ (your V is this case) and ‘string’ (your N in this case).

You’re right, Phillipe. After some other minor changes, now i can compile the codes. :smiley: Many thanks.

One undesirable feature is that I have to put all my headers into one file (defined two separate classes. ) and all implementations into another file. I am wondering whether there is better way to do this. i.e. two classes lives in two header files and two implementation files. Thank you again.

regards,

gma

Hi,

This doable as long as you add to the implementation file an ‘explicit instantiation’ for every single instantiation of the template (that you are anticipating). In general, this is of course not practical.

Usually, one would put the complete implementation of a class template in a single header file. Thus in your case you would have simply 2 header files. Plus one (or 2) source file with just the linkdef statements.

Cheers,
Philippe.

Many thanks. Phillipe.

regards,

gma