Dictionary generation for private templated class

Hi,

Since I wouldn’t categorise the following as a bug, I instead chose to describe by experience here, rather than in a bug report.

I’m trying to do something quite complicated. I define a class with the following structure:

[code]template< class T1 >
class A {

private:
template< class T2 >
class B : public TNamed {

};

B< T1 > member;
};[/code]

You’ll have to trust me that for the problem that I’m trying to solve this would be a very elegant solution. As you can see, the internal class inherits from TNamed, because I want to be able to stream it over the network in a PROOF session.

So now I’m trying to create a dictionary for class A with a few template argument types. (int, short, etc.) Unfortunately rootcint can’t understand my code correctly, so the generated dictionary source can’t be compiled.

I’ve been trying to play with how I declare the “member” variable, but even if I fully qualify it like

in its declaration, it is still put as

in the shadow class in the dictionary source. Since the shadow class has nothing to do with class A, this declarations doesn’t specify the internal class to gcc.

Of course the solution seems straightforward enough: I just have to get the declaration of B< T2 > out of A< T1 >, and make it a stand-alone class. But from a design point of view it would’ve been nicer if it could’ve been hidden.

I know ROOT is not too fond of using templated code heavily, so I don’t think anyone is to blame for not thinking of such a weird setup for generating a dictionary. I just wanted to report a restriction of rootcint, hoping that maybe at one point it could become able to handle such code. It’s already almost able to generate the correct code, I just have to correct this one line in the generated dictionary by hand, and it compiles. :frowning:

Cheers,
Attila

Hi,

So I changed my code and define two separate templated classes now. However now I think I’m seeing a real (conceptual) problem.

The example is still that class A is using class B for internal affairs. I’d like to be able to instantiate class A with simple primitives, and also with std::vector-s of simple primitives. For this reason I’ve created a specialisation of class B like this:

[code]template< class T >
class B : public TNamed {

ClassDef( B, 1 );
};

template< class T >
class B< std::vector< T > > : public TNamed {

ClassDef( B, 1 );
};[/code]

Now, this code is not correct like this, so much is clear. If I put the ClassDef macro in both the general and the specialised class, I get errors stating that there are too few template parameter lists in the code generated by rootcint. If I only put the ClassDef macro in the specialised class, then I get the same. If I only put it in the general class, then the code compiles, but I get a lot of warnings from rootcint that I didn’t put a ClassDef macro into a class which descends from TObject. The generated dictionary then compiles, but because it’s missing a lot of stuff, the created library is useless.

So the question is: Can I use this trick of defining template specialisations when generating dictionaries for my classes? Again, from a design point of view it would be very nice if I could…

Cheers,
Attila

Hi,

Just to close the “thread”… While I still couldn’t get the dictionary generation working for specialised templated classes, I could solve the problem in another way.

I wanted to write a specialised B class because some of the operators that I used on the template member variable are not defined for std::vector-s. (Like the + operator.) So I define them myself. This solution seems to work nicely, hiding the implementation details from the user. So I think I’ll stop with making the code more complicated at this point… :slight_smile:

Cheers,
Attila

Hi Attila,

I can indeed reproduce those problems (not trivial to fix) and have registered them in our database of tests.

And is also seemingly more elegant :slight_smile:

Cheers,
Philippe.