Problems with LinkDef file for templated class

Hi ROOTers,

So, I suspect that the following problem will result in a bug report – but since I’m not completely experienced with this sort of thing, I thought it would be best to ask on the forum first whether there were any obvious mistakes I’m making.

I have the following class (example only – a boiled-down version of a wrapper for std::vector I’m using):

//MyClass.h
#include "TObject.h"
#include <complex>

template <typename _Tp>
class MyClass : public TObject
{
  public:
    MyClass() : TObject() { SetData(0); }
    MyClass(TRootIOCtor*) : TObject() { SetData(0); }
    template <typename _Op> MyClass(const _Op& input) : TObject() { SetData(0); }
    template <typename _Op> SetData(const _Op& input) { fData = static_cast<_Tp>(input); }

    _Tp fData;

  ClassDef(MyClass, 1)
};

templateClassImp(MyClass)

(The MyClass(TRootIOCtor*) constructor is due to the workaround identified in https://savannah.cern.ch/bugs/?86195.)

I write the following LinkDef file:

// LinkDef.h
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ nestedclasses;

#pragma link C++ class MyClass<int>+;
#pragma link C++ class MyClass<double>+
#pragma link C++ class MyClass<complex<double> >+;

#pragma link C++ function MyClass<int>::MyClass<int>(const int&);
#pragma link C++ function MyClass<int>::MyClass<int>(const double&);
#pragma link C++ function MyClass<double>::MyClass<double>(const int&);
#pragma link C++ function MyClass<double>::MyClass<double>(const double&);
#pragma link C++ function MyClass<complex<double> >::MyClass<complex<double> >(const int&);
#pragma link C++ function MyClass<complex<double> >::MyClass<complex<double> >(const double&);
#pragma link C++ function MyClass<complex<double> >::MyClass<complex<double> >(const complex<double>&);

#pragma link C++ function MyClass<int>::SetData(const int&);
#pragma link C++ function MyClass<int>::SetData(const double&);
#pragma link C++ function MyClass<double>::SetData(const int&);
#pragma link C++ function MyClass<double>::SetData(const double&);
#pragma link C++ function MyClass<complex<double> >::SetData(const int&);
#pragma link C++ function MyClass<complex<double> >::SetData(const double&);
#pragma link C++ function MyClass<complex<double> >::SetData(const complex<double>&);

#endif

(The form of the links for templated constructors is discussed briefly in https://savannah.cern.ch/bugs/?86253.)

I am trying to make a shared library that can be read by cint. So, normally I would do:
rootcint -f Dict.C -c -Iroot-config --incdir MyClass.h LinkDef.h
g++ -fPIC root-config --cflags root-config --ldflags -shared -o MyClass.so Dict.C MyClass.h

However, when I run the rootcint command I get the following errors:
$ rootcint -f Dict.C -c -Iroot-config --incdir MyClass.h LinkDef.h
Error: Template class static_cast not defined MyClass.h:12:
Error: Template class static_cast not defined MyClass.h:12:
Syntax error: #pragma link LinkDef.h:10:
Error: Template class static_cast not defined MyClass.h:12:
Warning: #pragma link, function MyClass<complex >(const int&) not found LinkDef.h:16:
Warning: #pragma link, function MyClass<complex >(const double&) not found LinkDef.h:17:
Warning: #pragma link, function MyClass<complex >(const complex&) not found LinkDef.h:18:
Warning: #pragma link, function SetData(const int&) not found LinkDef.h:20:
Warning: #pragma link, function SetData(const double&) not found LinkDef.h:21:
Warning: #pragma link, function SetData(const int&) not found LinkDef.h:22:
Warning: #pragma link, function SetData(const double&) not found LinkDef.h:23:
Warning: #pragma link, function SetData(const int&) not found LinkDef.h:24:
Warning: #pragma link, function SetData(const double&) not found LinkDef.h:25:
Warning: #pragma link, function SetData(const complex&) not found LinkDef.h:26:
Warning: Error occurred during reading source files
Warning: Error occurred during dictionary source generation
!!!Removing Dict.C Dict.h !!!
Error: rootcint: error loading headers…

Any comments, help, or confirmation that there’s a bug would be greatly appreciated. :slight_smile:

Thanks!
Clayton

PS. I am running rev. 40784 from the trunk (8/31/2011). So, very recent!

Hi,

Try:#ifdef __CINT__ template <typename _Op> SetData(const _Op& input); #else template <typename _Op> SetData(const _Op& input) { fData = static_cast<_Tp>(input); } #endif

Cheers,
Philippe.

Hi pcanal,

Thanks for your quick response! And I have to apologize: I found an error in my code. I still am not able to generate the dictionary file, but I had omitted the return type for the SetData functions. The corrected code is

//MyClass.h
#include "TObject.h"
#include <complex>

template <typename _Tp>
class MyClass : public TObject
{
  public:
    MyClass() : TObject() { SetData(0); }
    MyClass(TRootIOCtor*) : TObject() { SetData(0); }
    template <typename _Op> MyClass(const _Op& input) : TObject() { SetData(0); }
    template <typename _Op> void SetData(const _Op& input) { fData = static_cast<_Tp>(input); }

    _Tp fData;

  ClassDef(MyClass, 1)
};

templateClassImp(MyClass)

The errors I get now are:
$ rootcint -f Dict.C -c -Iroot-config --incdir MyClass.h LinkDef.h
Syntax error: #pragma link LinkDef.h:10:
Warning: #pragma link, function MyClass<complex >(const int&) not found LinkDef.h:16:
Warning: #pragma link, function MyClass<complex >(const double&) not found LinkDef.h:17:
Warning: #pragma link, function MyClass<complex >(const complex&) not found LinkDef.h:18:
Warning: Error occurred during reading source files
Warning: Error occurred during dictionary source generation
!!!Removing Dict.C Dict.h !!!
Error: rootcint: error loading headers…

This does not change, though, when I add in your #ifdef. Any other possibilities?

Thanks for all of your time on this!
Clayton

[quote]Syntax error: #pragma link LinkDef.h:10:[/quote]The linkdef is missing a trailing semi-colon on line 10.

[quote]Warning: #pragma link, function MyClass<complex >(const int&) not found LinkDef.h:16:
Warning: #pragma link, function MyClass<complex >(const double&) not found LinkDef.h:17:
Warning: #pragma link, function MyClass<complex >(const complex&) not found LinkDef.h:18:[/quote]CINT is unable to properly instantiation those function (due to an internal deficiency). We have currently no plan to lift this restriction within CINT.

Cheers,
Philippe

Oy, yes – thanks for pointing that out!

Ah well – thanks for your patient help with this!

Clayton