C++ 为什么赢了';";“外部模板”;与共享的ptr一起工作?
我有一个(似乎)聪明的想法,在stdafx.h中使用C++ 为什么赢了';";“外部模板”;与共享的ptr一起工作?,c++,templates,visual-c++,visual-studio-2012,explicit-specialization,C++,Templates,Visual C++,Visual Studio 2012,Explicit Specialization,我有一个(似乎)聪明的想法,在stdafx.h中使用外部模板类std::shared_ptr,在#include之后立即使用,以防止std::shared_ptr在数百个文件中被冗余实例化,我可以将模板类std::shared_ptr放在一个.cpp中,以强制执行一个实例化,并希望节省编译/链接时间。然而,对生成的.cod和.obj文件的检查表明,shared_ptr代码在任何地方都被创建。但是,如果我在自己的模板类中使用完全相同的技术,它将按预期工作。shared\u ptr是否有什么特殊之处
外部模板类std::shared_ptr
,在#include
之后立即使用,以防止std::shared_ptr
在数百个文件中被冗余实例化,我可以将模板类std::shared_ptr
放在一个.cpp中,以强制执行一个实例化,并希望节省编译/链接时间。然而,对生成的.cod和.obj文件的检查表明,shared_ptr
代码在任何地方都被创建。但是,如果我在自己的模板类中使用完全相同的技术,它将按预期工作。shared\u ptr
是否有什么特殊之处阻止了这种使用?也许是
本身的某些东西迫使编译器在到达我的外部模板
语句之前创建一个实例化(我非常确定stdafx.h中没有更高级别的东西使用共享\u ptr
)
澄清:
// stdafx.h; included in every cpp in the project
#include <memory>
#include "SomeWidelyUsedClass.h" // no shared_ptr in here
// I expect this to prevent instantiation of std::shared_ptr<SomeWidelyUsedClass>
// in all compilation units that include this, except the one below.
extern template class std::shared_ptr<SomeWidelyUsedClass>;
//stdafx.h;包括在项目的每个cpp中
#包括
#在此处包括“SomeWidelyUsedClass.h”//no shared\u ptr
//我希望这可以防止std::shared_ptr的实例化
//在包含此项的所有编译单元中,以下编译单元除外。
外部模板类std::shared\u ptr;
然后:
//explicitTemplateInstances.cpp
#包括“stdafx.h”
//我希望这会导致std::shared\u ptr
//要在此编译单元中实例化
模板类std::shared_ptr;
以及:
//SomeOtherFile.cpp
#包括“stdafx.h”
#包括“一些广泛使用的class.h”
void foo()
{
//我希望SomeOtherFile.obj不会包含
//std::shared_ptr,因为它在stdafx.h中声明为extern
std::shared_ptr(新的一些广泛使用的类());
}
标准在§14.7.2/10中规定:
除了内联函数和类模板专门化之外,显式实例化声明具有
抑制所引用实体的隐式实例化的效果
我刚签入VS2013,std::shared_ptr的实现有一个内联构造函数。这可能是您的
外部模板被忽略的原因。有一些代码将有助于理解和诊断问题。不知道,这个问题看起来很合理。不过,我不知道答案。@RSahu是用代码编辑的,我记得您必须获得VS2013才能获得extern-template
支持,即使如此,它仍然是iffy@dlf根据它的支持来检查它,我相信就是这样。此外,我刚刚在MS文档中提到了这一点:“专门化中的extern关键字仅适用于在类主体外部定义的成员函数。在类声明中定义的函数被视为内联函数,并且总是实例化的。”实验证实了这一点。对于我在问题中提到的玩具模板类,如果我在类主体之外定义函数,extern-template
起作用。如果我在它里面定义它们,它就不会。
// ExplicitTemplateInstantiations.cpp
#include "stdafx.h"
// I expect this to cause std::shared_ptr<SomeWidelyUsedClass>
// to be instantiated in this compilation unit
template class std::shared_ptr<SomeWidelyUsedClass>;
// SomeOtherFile.cpp
#include "stdafx.h"
#include "SomeWidelyUsedClass.h"
void foo()
{
// I expect that SomeOtherFile.obj will not include an instantiation of
// std::shared_ptr<SomeWidelyUsedClass> since it was declared extern in stdafx.h
std::shared_ptr<SomeWidelyUsedClass>(new SomeWidelyUsedClass());
}