vs2010中的extern模板类,在源文件中具有显式的instanciation

时间:2015-08-26 12:13:48

标签: c++ visual-studio-2010 templates extern

在另一个question中,我得到了明确的模板实例化帮助。 有人建议使用:

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();
   };
};

并在cpp中定义显式实例

TemplateX.cpp

#inlcude "TemplateX.h" 

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

在Visual Studio 2010中,我收到Intellisence错误消息:

  

错误:&#39; extern模板&#39;不能遵循类的明确实例化#34; TemplateX :: help&#34; [与TData =双]

question我发现此错误时,用户认为这是VS2010的Intellisence中的错误。我的代码是否正确C ++代码?

SmartPointer<TemplateX<TData>>会发生什么。如果我正确的话,这将被隐式地实现,但是每个其他代码实体也会实现它。我是否还可以明确地实现SmartPointer?

修改

我在msdn description of extern template中找到了一个旁边节点:

  

专业化中的extern关键字仅适用于成员   在类的主体之外定义的函数。定义的功能   类声明中的内部被认为是内联函数   总是被实例化。

我想知道这是否是原因,为什么我的代码无法工作,因为我对class正文中的函数有定义。

我需要将定义放在标题中,因为我想允许其他人将模板与其他数据类型实例化。但我不希望模板的所有实例只出现在编译单元中。

我想知道为什么假设所有类函数都在内联声明中是内联的...这是否意味着正文中定义的模板的所有函数都内联到调用者?

有没有办法让函数不在标题中内联? 我知道如果你将这个函数移出类体,可以将它们留在标题中。

编辑2:

我将函数decleration移出了类体,但是将它们留在了标题中。问题依然存在。

编辑3:

我正在考虑解决方案。我声明了一个宏ExpImpTemplate,其中包含&#34; export&#34;如果编译或&#34;&#34;如果只包括标题。

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

ExpImpTemplate template class TemplateX<float>;

这有用吗?

TemplateX.cpp

#define ExportTemplateX 
#inlcude "TemplateX.h" 

1 个答案:

答案 0 :(得分:0)

Intelisense向您发出警告,因为extern template仅在那些未进行显式实例化的源文件中声明。

例如,将您的代码更改为此:

// 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();
   };
};

,然后在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();
}