Question

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());
}
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top