问题
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