在另一个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"
答案 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();
}