У меня была (на первый взгляд) блестящая идея использования extern template class std::shared_ptr<SomeWidelyUsedClass>
сразу после stdafx.h #include <memory>
чтобы предотвратить 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());
}
Стандарт гласит в §14.7.2 / 10:
За исключением встроенных функций и специализаций шаблонов классов, явные объявления экземпляров имеют
эффект подавления неявной реализации объекта, к которому они относятся.
Я только что проверил в VS2013 и реализации std::shared_ptr<>
там есть встроенный конструктор. Это, вероятно, причина, почему ваш extern template
игнорируется