Jump to content
  • Advertisement
Sign in to follow this  
BattleMetalChris

Template functions not being generated

This topic is 2751 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a Resource Manager class, which uses template functions to return shaders and materials. Here is the function for materials (the shader one is pretty much identical):

template <typename T>
T* ResourceManager::getMaterial(std::string name)
{
using rendering::MaterialBase;

MaterialBase* material;
if (m_materials.exists(name))
material = m_materials.getPointerToElement(name);
else
{
std::string message = "Could not find material: " + name;
MessageBox(0, message.c_str(), "Material load Fail", MB_OK);
return 0;
}
#if defined( DEBUG ) || defined( _DEBUG )
T* returnedMaterial = dynamic_cast<T*>(material);
if (!returnedMaterial)
{
std::string message = "Tried to cast Material " + name + " to invalid type";
MessageBox(0, message.c_str(), "Material load Fail", MB_OK);
}
return returnedMaterial;
#else
return static_cast<T*>(material);
#endif
}


I set up my materials during the resourceManager's initialisation, and using this function, I can get a pointer to a material using (for example) getMaterial<Lit_DiffuseTex>("WoodenPlanks");
Using a template lets me cast the base material class to the appropriate type before returning it.

The problem is that I get unresolved external errors when I try to use it from any other class other than from the ResourceManager, as if the compiler isn't generating the appropriate functions from the template. What's more, if I call the getMaterial function with a given typename from within the ResourceManager first, I don't get these errors anywhere - if I put a call to getMaterial<Lit_DiffuseTex>("WoodenPlanks") in the ResourceManager's initialisation routine and just don't use the returned material, I can then call the function using the same typename from anywhere and it works fine.

One thing, I'm trying to call this from a different namespace than that used by the ResourceManager, could that be causing it?


I suppose if all else fails, I could ditch the template and have it return the base class, and have the calling object deal with casting, but it would be nice to keep the slightly messy casting in one place.

Share this post


Link to post
Share on other sites
Advertisement
Well, for starters, you have to have the full template available at the point of use. So, in some header that is included by all your files that need the getMaterial, you need to have

template <typename T> T* ResourceManager::getMaterial(std::string name)
{
//...
}

You can't just have the function declaration in the header, and the definition in some cpp. Templates don't work like normal functions in that regard.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!