1

In another question I was helped with explicit instanciation of templates. It was suggested to use:

TemplateX.h:

extern template class TemplateX<double>;
extern template class TemplateX<float>;

template<class TData>
class TemplateX 
{
    typedef TemplateX<TData>               Self;
    typedef SmartPointer<TemplateX<TData>> Pointer;

public:
   void help()
   {
      return ;
   };
   static Pointer New()
   {
      return Pointer();
   };
};

and define the explicit instanciation in the cpp

TemplateX.cpp

#inlcude "TemplateX.h" 

template class TemplateX<double>;
template class TemplateX<float>;

In Visual Studio 2010 I get an Intellisence Error Message:

Error: 'extern template' cannot follow explicit instantiation of class "TemplateX::help" [with TData=double]

In an question I found to this error the user assumed this is a bug in Intellisence of VS2010. Is my code correct C++ Code?

What will happen to the SmartPointer<TemplateX<TData>>. If I'm correct this will be implicitly instanciated, but every other code entity, will also instanciat it. Can I also explicitly instanciat the SmartPointer?

Edit:

I found a side node in the msdn description of extern template:

The extern keyword in the specialization only applies to member functions defined outside of the body of the class. Functions defined inside the class declaration are considered inline functions and are always instantiated.

I wonder if this could be the reason, why my code won't work, because I have the definitions of the functions in the class body.

I need the definitions to be in the header because I want to allow others to instanciate the template with other data types. But I wan't to have all instanciations of the template to only be present in on compilation unit.

I'm wondering why all class functions are assumed to be inline if they are in the class declaration... Does this mean all functions of templates defined with definitions in the body are inlined to the caller?

Is there a way to make the functions not inline in the header? I read it is possible if you move the function out of the class body, but leave them in the header.

Edit 2:

I moved the function decleration out of the class body, but left them in the header. The problem still exists.

Edit 3:

I'm thinking about a solution. I declare a Macro ExpImpTemplate which holds "export" if compiling or "" if just including the header.

#if defined(!ExportTemplateX)
 #define ExpImpTemplate
#else 
 #define ExpImpTemplate extern
#endif

ExpImpTemplate template class TemplateX<float>;

Could this help?

TemplateX.cpp

#define ExportTemplateX 
#inlcude "TemplateX.h" 
Community
  • 1
  • 1
GiCo
  • 566
  • 4
  • 19

1 Answers1

1

Intelisense is giving you a warning because extern template must be declared only in those source files where explicit instantation does not take place.

for example change your code to this:

// DO NOT DECLARE HERE
// extern template class TemplateX<double>;
// extern template class TemplateX<float>;

template<class TData>
class TemplateX 
{
    typedef TemplateX<TData>               Self;
    typedef SmartPointer<TemplateX<TData>> Pointer;

public:
   void help()
   {
      return ;
   };
   static Pointer New()
   {
      return Pointer();
   };
};

and define the explicit instanciation in the cpp

TemplateX.cpp

#inlcude "TemplateX.h" 

// it would be intelisense error to declare 'extern template' here
template class TemplateX<double>;
template class TemplateX<float>;

SomeOtherSourceFileUsingTheTemplate.cpp

#inlcude "TemplateX.h"
extern template class TemplateX<double>;
extern template class TemplateX<float>;

// use externaly compiled template here, ie. don't compile here...

void f()
{
       TemplateX<double> Object;
       Object.help();
}