Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Aggiornamento: novembre 2007
Grazie alle operazioni di conformità di Visual C++ è consentito l'overload di specializzazioni di modelli di funzione e di modelli normali.
L'esempio riportato di seguito viene compilato in Visual Studio .NET 2003, ma avrà esito negativo in Visual Studio .NET:
// bc_exported_templ_instan.cpp
template<typename T, typename U>
T ConvertTo(const U &u) {
return static_cast<T>(u);
}
char ConvertTo(const int &i) {
return static_cast<char>(i);
}
int main() {
char c1 = ConvertTo(1);
char c2 = ConvertTo<char, int>(2);
}
Per supportare l'overload di specializzazioni di modelli di funzione e modelli normali, è stata modificata la modalità di creazione di nomi decorati per le specializzazioni di modelli di funzione del compilatore. Un nome decorato aggiornato ora include la codifica degli argomenti di modello, nonché la codifica del parametro della funzione e dei tipi restituiti. Per le funzioni nell'esempio precedente, il compilatore C++ in Visual Studio .NET 2003 genererà le seguenti decorazioni dei nomi:
?ConvertTo@@YADABH@Z – char ConvertTo(const int &);
??$ConvertTo@DH@@YADABH@Z – char ConvertTo<char, int>(const int &);
Questo non comporta modifiche alla modalità di sviluppo delle applicazioni. Un caso in cui questa modifica influisce sugli utenti è quello relativo all'esportazione di una specializzazione di un modello di funzione da una DLL utilizzata in un'applicazione che non è stata ricompilata con il compilatore nuovo. Di seguito è riportato un esempio:
// bc_exported_templ_instan2.h
#include <iostream>
#ifdef _DLL_EXPORT
#define DLL_LINKAGE __declspec(dllexport)
#else
#define DLL_LINKAGE __declspec(dllimport)
#endif
template<typename T>
void f(const T &rT) {
std::cout << "i = " << rT << std::endl;
}
template DLL_LINKAGE void f<int>(const int &);
Il seguente codice verrà compilato per la creazione della DLL:
// bc_exported_templ_instan2.cpp
// compile with: /D_DLL_EXPORT /EHsc /LD
#include "bc_exported_templ_instan2.h"
Se viene effettuata la seguente operazione:
dumpbin /exports bc_exported_templ_instan2.dll
Sarà possibile notare che il nome decorato della specializzazione esportata del modello di funzione è ??$f@H@@YAXABH@Z.
Se un'applicazione esistente dipende da questa DLL e tale applicazione è stata compilata con il compilatore di Visual C++ in Visual Studio .NET o una versione precedente e non è possibile ricompilare questa applicazione, verrà generato un errore in fase di compilazione, dal momento che l'applicazione prevede un punto di ingresso con il nome obsoleto. Tuttavia, la nuova DLL esporterà solo una funzione con il nome nuovo.
// bc_exported_templ_instan3.cpp
// compile with: /EHsc /link bc_exported_templ_instan2.lib
#include "bc_exported_templ_instan2.h"
int main() {
f(1);
}
Per risolvere il problema, è necessario modificare la modalità di compilazione della DLL in modo che sia il nome obsoleto che quello nuovo per la specializzazione del modello di funzione verranno esportati. Questa operazione viene eseguita con l'uso / esportazione al programma di collegamento. Di seguito è riportato un esempio:
cl /D_DLL_EXPORT /EHsc /LD a.cpp /link /export:?f@@YAXABH@Z=??$f@H@@YAXABH@Z
In tal caso viene indicato al collegamento di creare un'esportazione per entrambi i nomi specificati, ma di eseguire il mapping nello stesso simbolo.