Tuesday, May 29, 2018

c++ - Unresolved external symbol with template function



I searched around the web but I haven't found an answer yet, as to why I get this error:





Error 1 error LNK2019: unresolved external symbol "public: class Mesh * __thiscall AssetManager::GetAsset(class std::basic_string,class std::allocator >)" (??$GetAsset@PAVMesh@@@AssetManager@@QAEPAVMesh@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: void __thiscall SceneManager::AddMesh(class std::basic_string,class std::allocator >)" (?AddMesh@SceneManager@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) C:\Users\Dirk\documents\visual studio 2010\Projects\OpenGameEngine\OpenGameEngine\SceneManager.obj




Here is my code:



AssetManager.h



#pragma once

#include
#include
#include "Asset.h"
#include "Mesh.h"

using namespace std;

class AssetManager
{
public:

AssetManager(string rootFolder);
bool LoadAsset(string assetName, int assetType, string assetFile, bool subDirectory);
void UnloadAsset(string assetName);
template T GetAsset(string assetName);
bool AddAssetSubDirectory(int assetType, string subDirectory);

private:
string m_rootFolder;
map m_assetSubs;
map m_assets;

};


AssetManager.cpp



#include "AssetManager.h"

AssetManager::AssetManager(string rootFolder)
{
m_rootFolder = rootFolder;

}

bool AssetManager::AddAssetSubDirectory(int assetType, string subDirectory)
{
if (m_assetSubs.find(assetType) == m_assetSubs.end())
{
m_assetSubs[assetType] = subDirectory;
return true;
}
else

{
return false;
}
}

bool AssetManager::LoadAsset(string assetName, int type, string assetFile, bool subDirectory)
{
string filePos;
if (subDirectory)
{

filePos = m_rootFolder.append(m_assetSubs[type]).append(assetFile);
}
else
{
filePos = m_rootFolder.append(assetFile);
}
return true;
}

void AssetManager::UnloadAsset(string assetName)

{
if (m_assets.find(assetName) != m_assets.end())
{
m_assets.erase(assetName);
}
}

template T AssetManager::GetAsset(string assetName)
{
if (m_assets.find(assetName) != m_assets.end())

{
return m_assets[assetName];
}
else
{
return null;
}
}



SceneManager.h



#pragma once
#include
#include
#include "AssetManager.h"

using namespace std;

class SceneManager

{
public:
static SceneManager* Instance();
void AddMesh(string assetName);
void RemoveMesh(string assetName);
void Draw();
void Run();
void SetAssetManager(AssetManager*);
void Destroy();


private:
SceneManager();
SceneManager(SceneManager const&);
~SceneManager();
SceneManager& operator=(SceneManager const&){};
static SceneManager* m_Instance;
AssetManager *m_assetMgr;

private:
map m_staticMeshes;

};


SceneManager.cpp



#include "SceneManager.h"
#include "AssetManager.h"

SceneManager* SceneManager::m_Instance = NULL;


SceneManager::SceneManager()
{
m_assetMgr = 0;
}

SceneManager::SceneManager(SceneManager const&)
{

}


SceneManager::~SceneManager()
{
delete m_assetMgr;
m_assetMgr = 0;
}

void SceneManager::Destroy()
{
delete m_Instance;
m_Instance = 0;

}

SceneManager* SceneManager::Instance()
{
if (!m_Instance)
m_Instance = new SceneManager();

return m_Instance;
}


void SceneManager::SetAssetManager(AssetManager *am)
{
m_assetMgr = am;
}

void SceneManager::AddMesh(string assetName)
{
m_assetMgr->GetAsset(assetName);
}


void SceneManager::RemoveMesh(string assetName)
{
if (m_staticMeshes.find(assetName) != m_staticMeshes.end())
{
m_staticMeshes.erase(assetName);
}
}

void SceneManager::Draw()
{

for (map::Iterator it = m_staticMeshes.begin(); it != m_staticMeshes.end(); ++it)
{
it->second->Draw();
}
}

void SceneManager::Run()
{

}



Thanks in advance for the responses!


Answer



C++ does not allow you to declare a template in a header file and define it in a .cpp file. The reason is that templates can only be created when the template parameters are known and so they can't be complied in advance.



To solve your problem, you will need to declare and define template T GetAsset(string assetName) in the AssetManager.h file


No comments:

Post a Comment

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...