5

Avevo l'idea (apparentemente) di utilizzare extern template class std::shared_ptr<SomeWidelyUsedClass> in stdafx.h immediatamente dopo #include <memory> per impedire che std::shared_ptr<SomeWidelyUsedClass> venisse istanziato in modo ridondante in centinaia di file, immaginando di poter inserire template class std::shared_ptr<SomeWidelyUsedClass> in un singolo .cpp per forzare un singolo istanziazione e si spera che risparmi tempo di compilazione/collegamento. Tuttavia, l'esame dei file .cod e .obj risultanti mostra che il codice shared_ptr<SomeWidelyUsedClass> viene creato ovunque in ogni caso. Ma se uso questa stessa identica tecnica con la mia classe template, funziona come previsto. C'è qualcosa di speciale nello shared_ptr che preclude questo utilizzo? Forse qualcosa nello stesso <memory> che costringe il compilatore a creare un'istanza prima che raggiunga la mia istruzione extern template (sono sicuro che non c'è niente di più alto in stdafx.h che faccia uso di shared_ptr)?Perché "extern template" non funziona con shared_ptr?

per chiarire:

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

Poi:

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

E:

// 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()); 
} 
+0

Avere del codice sarà utile per capire e diagnosticare il problema. –

+0

Dunno, la domanda sembra abbastanza ragionevole così com'è. Non so la risposta, però. –

+0

@RSahu modificato con il codice – dlf

risposta

6

Lo standard dice nel §14.7.2/10:

Exce pt per le funzioni inline e le specializzazioni dei modelli di classe, le dichiarazioni di istanziazione esplicite hanno l'effetto di sopprimere l'istanza implicita dell'entità a cui si riferiscono.

Ho appena controllato VS2013 e l'implementazione di std::shared_ptr<> ha un costruttore in linea. Questo è probabilmente il motivo per cui il tuo extern template viene ignorato.

+1

Credo che sia così. Inoltre, sono stato indirizzato a questa nota nei documenti MS: "La parola chiave extern nella specializzazione si applica solo alle funzioni membro definite al di fuori del corpo della classe.Le funzioni definite all'interno della dichiarazione di classe sono considerate funzioni inline e sono sempre istanziate ". – dlf

+0

L'esperimento lo conferma. Per la classe template giocattolo a cui ho fatto riferimento nella domanda, se definisco le funzioni al di fuori del corpo della classe, 'extern template' funziona. Se li definisco al suo interno, non lo fa. – dlf

Problemi correlati