6

为了防止在数百个文件中被冗余实例化,我有一个(看似)聪明的想法,extern template class std::shared_ptr<SomeWidelyUsedClass>即立即在 stdafx.h中使用,我认为我可以放置在单个 .cpp 中以强制进行单个实例化并希望节省编译/链接时间。但是,对生成的 .cod 和 .obj 文件的检查表明,无论如何都在到处创建代码。但是,如果我在自己的模板类中使用这种完全相同的技术,它就会按预期工作。有什么特别的地方排除了这种用途吗?也许某些东西本身会迫使编译器在它到达我的语句之前创建一个实例化(我很确定在 stdafx.h 中没有任何更高的东西可以使用)?#include <memory>std::shared_ptr<SomeWidelyUsedClass>template class std::shared_ptr<SomeWidelyUsedClass>shared_ptr<SomeWidelyUsedClass>shared_ptr<memory>extern templateshared_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>;

然后:

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

1 回答 1

7

该标准在 §14.7.2/10 中说:

除了内联函数和类模板特化,显式实例化声明具有抑制它们所引用实体的隐式实例化的效果。

我刚刚签入了 VS2013,那里的实现std::shared_ptr<>有一个内联构造函数。extern template这可能是您被忽略的原因。

于 2014-05-01T17:32:13.377 回答