A link problem with c++ template function
-
template< size_t N >
void cdecl _DumpWin32StructFields( WCHAR (&szBuffer)[N], LPCWSTR pszFormat, ... )
{
va_list pFirstParam ;
va_start( pFirstParam, pszFormat ) ;
StringCchVPrintf( szBuffer, N,pszFormat, pFirstParam ) ;
va_end( pFirstParam ) ;
}If I put the function definition in a different obj file than the caller, it fails to link reporting I didn't give definition to _DumpWin32StructFields, actually I do,in another obj, it's just too stupid for the linker to find out. Is there a solution if I don't put caller and the function together?
-
template< size_t N >
void cdecl _DumpWin32StructFields( WCHAR (&szBuffer)[N], LPCWSTR pszFormat, ... )
{
va_list pFirstParam ;
va_start( pFirstParam, pszFormat ) ;
StringCchVPrintf( szBuffer, N,pszFormat, pFirstParam ) ;
va_end( pFirstParam ) ;
}If I put the function definition in a different obj file than the caller, it fails to link reporting I didn't give definition to _DumpWin32StructFields, actually I do,in another obj, it's just too stupid for the linker to find out. Is there a solution if I don't put caller and the function together?
A template class or template function is resolved during compile time. Symbols in an OBJ file are resolved during link time. So to use templates, you have to provide template source access to the calling file. The problem you're facing is not because the linker is stupid. It's because it's the compiler that resolves templates and not the linker.
«_Superman_» _I love work. It gives me something to do between weekends.
-
A template class or template function is resolved during compile time. Symbols in an OBJ file are resolved during link time. So to use templates, you have to provide template source access to the calling file. The problem you're facing is not because the linker is stupid. It's because it's the compiler that resolves templates and not the linker.
«_Superman_» _I love work. It gives me something to do between weekends.
Thanks, I think you are right. I searched some materials, says the compiler won't embed the template definition( blueprint ) into an obj until it is called. So I simply put it in a common header file, but I am still worried if more than one cpp call the template with the same function prototype.
-
template< size_t N >
void cdecl _DumpWin32StructFields( WCHAR (&szBuffer)[N], LPCWSTR pszFormat, ... )
{
va_list pFirstParam ;
va_start( pFirstParam, pszFormat ) ;
StringCchVPrintf( szBuffer, N,pszFormat, pFirstParam ) ;
va_end( pFirstParam ) ;
}If I put the function definition in a different obj file than the caller, it fails to link reporting I didn't give definition to _DumpWin32StructFields, actually I do,in another obj, it's just too stupid for the linker to find out. Is there a solution if I don't put caller and the function together?
If you want to use a function from different cpp files you have to make the declaration (the function signature) available to both. In the case of a template function, the same goes for its definition! To avoid code duplication, the right place to put this is a header file, not a cpp file.
// file dump.hpp
template< size_t N >
void cdecl _DumpWin32StructFields( WCHAR (&szBuffer)[N], LPCWSTR pszFormat, ... )
{
va_list pFirstParam ;
va_start( pFirstParam, pszFormat ) ;
StringCchVPrintf( szBuffer, N,pszFormat, pFirstParam ) ;
va_end( pFirstParam ) ;
}// file foo.cpp
#include "dump.hpp"
void foo() {
WCHAR buffer[20];
_DumpWin32StructFields(buffer, _T("Hello World!"));
}// file bar.cpp
#include "dump.hpp"
void bar() {
WCHAR buffer[30];
_DunpWin32StructFields(buffer, _T("Goodbye Cruel World!"));
}This will force the compiler to instantiate and create code for your template function for both foo.obj and bar.obj, and the linker won't have trouble finding them.