Why won't “extern template” work with shared_ptr?

独自空忆成欢 提交于 2019-12-21 05:15:17

问题


I had the (seemingly) bright idea of using extern template class std::shared_ptr<SomeWidelyUsedClass> in stdafx.h immediately after #include <memory> in order to prevent std::shared_ptr<SomeWidelyUsedClass> from being redundantly instantiated in hundreds of files, figuring I could place template class std::shared_ptr<SomeWidelyUsedClass> in a single .cpp in order to force a single instantiation and hopefully save on compile/link time. However, examination of the resulting .cod and .obj files shows that shared_ptr<SomeWidelyUsedClass> code is being created everywhere anyway. But if I use this exact same technique with my own template class, it works as expected. Is there something special about shared_ptr that precludes this use? Perhaps something in <memory> itself that forces the compiler to create an instantiation before it reaches my extern template statement (I'm very certain there's nothing higher up in stdafx.h that makes use of shared_ptr)?

To clarify:

// 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>;

Then:

// 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>;

And:

// 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:


The standard says in §14.7.2/10:

Except for inline functions and class template specializations, explicit instantiation declarations have the effect of suppressing the implicit instantiation of the entity to which they refer.

I just checked in VS2013 and the implementation of std::shared_ptr<> there has an inline constructor. This is probably the reason why your extern template is ignored.



来源:https://stackoverflow.com/questions/23411524/why-wont-extern-template-work-with-shared-ptr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!