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

时间:2014-05-01 16:03:01

标签: c++ templates visual-c++ visual-studio-2012 explicit-specialization

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

1 个答案:

答案 0 :(得分:6)

标准在§14.7.2/ 10中说:

  

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

我刚刚在VS2013中检查过,std::shared_ptr<>的实现有一个内联构造函数。这可能是您忽略extern template的原因。