c++ - vs2010中的extern模板类在源文件中具有显式实例化

标签 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 错误消息:

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

question中我发现这个错误用户认为这是 VS2010 Intellisence 中的一个错误。我的代码是正确的 C++ 代码吗?

SmartPointer<TemplateX<TData>> 会发生什么? 。如果我是正确的,这将被隐式实例化,但所有其他代码实体也会实例化它。我还可以显式实例化 SmartPointer 吗?

编辑:

我在 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.

我想知道这是否可能是我的代码无法工作的原因,因为我在class中有函数的定义。 body 。

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

我想知道为什么如果所有类函数都在类声明中,则假定它们是内联的...这是否意味着使用主体中的定义定义的模板的所有函数都内联到调用者?

有没有办法使函数不在标题中内联? 我读到,如果将函数移出类主体,但将它们保留在标题中,这是可能的。

编辑2:

我将函数减速移出类主体,但将它们留在标题中。问题仍然存在。

编辑3:

我正在考虑解决方案。我声明一个宏ExpImpTemplate如果编译则保存“export”,如果仅包含 header 则保存“”。

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

ExpImpTemplate template class TemplateX<float>;

这有帮助吗?

TemplateX.cpp

#define ExportTemplateX 
#inlcude "TemplateX.h" 

最佳答案

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

关于c++ - vs2010中的extern模板类在源文件中具有显式实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32226350/

相关文章:

c++ - 在 C++ 中初始化静态数组

c++ - 即使在 Visual Studio 2010 中访问变量时也会出现 C2326 错误

xml - 将参数从 Visual Studio 项目模板传递到生成的项目

c++ - template 模板参数场景

c++ - 模板和 STL

c++ - 如何查看 GDB 中自动变量的内存地址?

c++ - 破坏空指针时的访问冲突

C++ 可变参数模板打包到 std::array 并解包

wpf - 自动创建getter/setter的代码片段?

visual-studio-2010 - 无法通过 msbuild 获取 powershell 脚本来导入模块