为什么"extern模板"不能与shared_ptr一起使用?

dlf*_*dlf 5 c++ templates visual-c++ explicit-specialization visual-studio-2012

为了防止在数百个文件中进行冗余实例化,我有了(似乎)明确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>;
Run Code Online (Sandbox Code Playgroud)

然后:

// 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>;
Run Code Online (Sandbox Code Playgroud)

和:

// 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());
}
Run Code Online (Sandbox Code Playgroud)

小智 6

标准在§14.7.2/ 10中说:

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

我刚刚检查了VS2013,并且std::shared_ptr<>有一个内联构造函数的实现.这可能是您extern template被忽略的原因.