   [C++] Mysterious linker error ... explicit template specialization involved
  Hello,Visual C++ 2005 is giving me the following linker error:Quote:error LNK2019: unresolved external symbol "private: static unsigned int __cdecl USS_Lib::Device::formatParameterValueForWrite<class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > >(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &,class USS_Lib::USS_ParamDesc const &)" (??$formatParameterValueForWrite@V?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Device@USS_Lib@@CAIABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@ABVUSS_ParamDesc@1@@Z) referenced in function "public: void __thiscall USS_Lib::Device::writeParameter_singleIndex<class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > >(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &,unsigned int,unsigned int)" (??$writeParameter_singleIndex@V?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Device@USS_Lib@@QAEXABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@II@Z)Prior to the linker stage, I get the following compiler warning:Quote:warning C4506: no definition for inline function 'USS_Lib::dword USS_Lib::Device::formatParameterValueForWrite<USS_Lib::String>(const USS_Lib::String &,const USS_Lib::USS_ParamDesc &)'The compiler warning in particular has got me stomped since formatParameterValueForWrite() is most definitely not an inline function ... at least I don't think so ... I never declared it as inline nor did I implement it in the class body.The formatParameterValueForWrite() is a static template method in my Device class. I've added an explicit specialization of the formatParameterValueForWrite() template for cases where T = String (String is typdef'd to std::basic_string< TCHAR >).// general template (definition in the same header file but outside the class)template < typename SourceValueType >    static dword formatParameterValueForWrite( const SourceValueType& value, const USS_ParamDesc& desc );// specialization for T = String (definition in the cpp)template <>    static dword formatParameterValueForWrite< String >( const String& value, const USS_ParamDesc& desc );Additionally, there is another template method called writeParameter_singleIndex(). This is where the formatParameterValueForWrite() method is actually referenced.template < typename SourceValueType >void USS_Lib::Device::writeParameter_singleIndex(    const SourceValueType& value,    ParamId_t paramId,    ParamIndex_t paramIndex){    // ...    // here I'm actually calling the formatParameterValueForWrite() method    const dword bitPattern = formatParameterValueForWrite< SourceValueType >( value, *pDesc );   // ...}Does anyone see what I'm doing wrong?   
  Are you linking more than one project / library? Maybe you should check that project settings match (such as unicode / multibyte and lots more).   ;  Hi,Yes, I am. The code I've posted is in a library. The application makes use of the functions / classes defined in this library. UNICODE / MBCS, debug / release, single-threaded, multi-threaded, etc. settings match for all components of the solution. I mean everything compiled, linked and ran just fine before I started adding these 2 template methods.   ;  Hmmm, the fact that these template methods are in a library does appear to have something to do with it. I've just added a test() method to the library that does nothing more than reference (call) my template methods (with T = String) ... and suddenly the linker error is gone (but the compiler warning is still there).Am I not supposed to use explicit template specialization in a library?? :-(   ;  Alright, I've done some reading on the web, and the solution is to make my template specialization inline and move its implementation from the cpp to the header. That fixes the problem but it doesn't really make me happy because it also means I have to move a whole bunch of #includes from my cpp to my header as well, which doesn't exactly benefit compile times. :-(   ;  Hello RedAnt,How about factoring the specialized code out into a non-template helper function? This helper function can then be called from the template specialization.This will allow headers that are only used by the helper function to remaining out of the templated header file.For Example: Adding the helper function "formatParameterValueForWriteStringImpl"// general template (definition in the same header file but outside the class)template < typename SourceValueType >    static dword formatParameterValueForWrite( const SourceValueType& value, const USS_ParamDesc& desc );// specialization for T = String (definition in lined in the class, calls non-template worker function)template <>    static dword formatParameterValueForWrite< String >( const String& value, const USS_ParamDesc& desc )    { return formatParameterValueForWriteStringImpl( value, desc ) };// non-templated worker function (definition in a cpp)dword formatParameterValueForWriteStringImpl( const String& value, const USS_ParamDesc& desc ){   ... perform the real work here ..}Cheers,Tom   ;  Excellent idea! :-) Why didn't I think of that? Haha ...   