views:

469

answers:

3

I have a class named "SimObject":

namespace simBase
{
    class __declspec(dllexport) SimObject: public SimSomething
    {
        public:

            template <class T>
            void updateParamValue( const std::string& name, T val );
    }
}

I have another class named "ITerrainDrawable":

namespace simTerrain
{
    class __declspec(dllexport) ITerrainDrawable : public simBase::SimObject
    {
    }
}

These classes are in different libraries. SimObject is in simBase, ITerrainDrawable is in simTerrain libraries. Even if ITerrainDrawable is derived from SimObject and I included library of simBase, I get a link error:

unresolved external symbol

1>ITerrainDrawable.obj : error LNK2019: unresolved external symbol "public: void __thiscall simBase::SimObject::updateParamValue<float>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,float)" (??$updateParamValue@M@SimObject@simBase@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@Z) referenced in function "public: void __thiscall simTerrain::ITerrainDrawable::setTerrainSize(float)" (?setTerrainSize@ITerrainDrawable@simTerrain@@QAEXM@Z)
1>ITerrainDrawable.obj : error LNK2019: unresolved external symbol "public: void __thiscall simBase::SimObject::updateParamValue<class osg::Vec4f>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class osg::Vec4f)" (??$updateParamValue@VVec4f@osg@@@SimObject@simBase@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@VVec4f@osg@@@Z) referenced in function "public: void __thiscall simTerrain::ITerrainDrawable::setSatelliteTextureBorders(class osg::Vec2f,class osg::Vec2f)" (?setSatelliteTextureBorders@ITerrainDrawable@simTerrain@@QAEXVVec2f@osg@@0@Z)

Why do I get this error?

Everything works fine if I don't use template function but I need it.

If I move this function to simTerrain library it works fine but I don't want to use duplicate function because there are many libraries like simTerrain.

+3  A: 

C++ does not really support the separate compilation of template code - you need to put the definition of the template in a header file.

anon
thanks Neil :) it worked when i move the function definition to the header
ufukgun
+6  A: 

The full implementation of a template class must be in that template class's header. The ANSI/ISO standards for C++ allow for a way to put the implementation in a separate compilation unit using the export keyword , but there are currently any compilers that actually support this.

For more information read this and this.

Prasoon Saurav
i use VisualStudio2008 and the response to export is : warning C4237: 'export' keyword is not yet supported, but reserved for future use
ufukgun
+2  A: 

There are two compilation model for templates :

  1. Inclusion compilation model ( like including header file )
  2. Separate compilation model ( separation of interface from implementation )

You can use export keyword at time of template definition for 2nd option.

export template <class T>
void updateParamValue( const std::string& name, T val ) {}

But I am not sure that all compiler supports it.

Ashish
i use VisualStudio2008 and the response to export is : warning C4237: 'export' keyword is not yet supported, but reserved for future use
ufukgun
vc++ 7.0 does not support it , may be next version might have support of it.But I run it on linux GNU C++ 8.2 compiler which supports it.
Ashish
i wish your answer be true but stupid vs does not support it yet :/ i dont like to write function definitions to header.
ufukgun