1
General / sfml game development book (2013) - chapter 2 enum issue
« on: February 08, 2023, 11:29:10 pm »
Hello SFML community x) , as I was following sfml game development book in chapter 2 where they implemented ResourceHolder class so I tried to use the class within the main but unfortunately I run into a linking error x( . I guess it has to do with the enum class TextureID . The error message says :
as for the source code for both ResourceHolder.h and ResourceHolder.cpp :
as for the error, it occurs when i declare a variable with ResourceHolder class .
as for the enum it's declared in main.cpp as follow :
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "public: __cdecl ResourceHolder<class sf::Texture,enum TexturesID>::~ResourceHolder<class sf::Texture,enum TexturesID>(void)" (??1?$ResourceHolder@VTexture@sf@@W4TexturesID@@@@QEAA@XZ) referenced in function main SFML C:\Courses\CPP\Tutorial\Chapter 1\SFML\SFML\SFML.obj 1
Error LNK2019 unresolved external symbol "public: __cdecl ResourceHolder<class sf::Texture,enum TexturesID>::~ResourceHolder<class sf::Texture,enum TexturesID>(void)" (??1?$ResourceHolder@VTexture@sf@@W4TexturesID@@@@QEAA@XZ) referenced in function main SFML C:\Courses\CPP\Tutorial\Chapter 1\SFML\SFML\SFML.obj 1
as for the source code for both ResourceHolder.h and ResourceHolder.cpp :
#ifndef RESOURCE_HOLDER_H
#define RESOURCE_HOLDER_H
#include <map>
#include <string>
#include <memory>
#include <stdexcept>
#include <cassert>
#include <SFML/Graphics.hpp>
template<typename Resource, typename Identifier>
class ResourceHolder
{
public:
ResourceHolder();
~ResourceHolder();
public:
void load(Identifier ID,const std::string& filename);
template<typename Parameter>
void load(Identifier ID, const std::string& filename, Parameter parameter);
Resource& get(Identifier ID);
const Resource& get(Identifier ID) const;
private:
std::map <Identifier,
std::unique_ptr<Resource> > mResourceMap;
};
#endif
#define RESOURCE_HOLDER_H
#include <map>
#include <string>
#include <memory>
#include <stdexcept>
#include <cassert>
#include <SFML/Graphics.hpp>
template<typename Resource, typename Identifier>
class ResourceHolder
{
public:
ResourceHolder();
~ResourceHolder();
public:
void load(Identifier ID,const std::string& filename);
template<typename Parameter>
void load(Identifier ID, const std::string& filename, Parameter parameter);
Resource& get(Identifier ID);
const Resource& get(Identifier ID) const;
private:
std::map <Identifier,
std::unique_ptr<Resource> > mResourceMap;
};
#endif
#include "ResourceHolder.h"
template<typename Resource, typename Identifier>
void ResourceHolder<Resource, Identifier>::load(Identifier ID, const std::string& filename)
{
std::unique_ptr<Resource> resourcePtr = std::make_unique<Resource>(new Resource());;
if (!resourcePtr->loadFromFile(filename))
throw std::runtime_error("ResourceHolder - Failed to load file : " + filename);
auto inserted = mResourceMap.insert(std::make_pair(ID, std::move(resourcePtr)));
assert(!inserted.second);
}
// this function is used when dealing with sahders, as loadFromFile function in shaders has two parameters
template<typename Resource, typename Identifier>
template<typename Parameter>
void ResourceHolder<Resource, Identifier>::load(Identifier ID, const std::string& filename, Parameter parameter)
{
std::unique_ptr<Resource> resourcePtr = std::make_unique<Resource>(new Resource());
if (!resourcePtr->loadFromFile(filename, parameter))
throw std::runtime_error("ResourceHolder - Failed to load file : " + filename);
auto inserted = mResourceMap.insert(std::make_pair(ID,std::move(resourcePtr))) ;
assert(!inserted.second && "ResourceHolder<Resource, Identifier>::load : function that takes 3 parameters");
}
template<typename Resource, typename Identifier>
Resource& ResourceHolder<Resource, Identifier>::get(Identifier ID)
{
auto found = mResourceMap.find(ID);
assert(found != mResourceMap.end() && "the given ID already exist in mResourceMap");
return found->second;
}
template<typename Resource, typename Identifier>
const Resource& ResourceHolder<Resource, Identifier>::get(Identifier ID) const
{
auto found = mResourceMap.find(ID);
assert(found != mResourceMap.end() && "the given ID already exist in mResourceMap");
return *found->second;
}
template<typename Resource, typename Identifier>
void ResourceHolder<Resource, Identifier>::load(Identifier ID, const std::string& filename)
{
std::unique_ptr<Resource> resourcePtr = std::make_unique<Resource>(new Resource());;
if (!resourcePtr->loadFromFile(filename))
throw std::runtime_error("ResourceHolder - Failed to load file : " + filename);
auto inserted = mResourceMap.insert(std::make_pair(ID, std::move(resourcePtr)));
assert(!inserted.second);
}
// this function is used when dealing with sahders, as loadFromFile function in shaders has two parameters
template<typename Resource, typename Identifier>
template<typename Parameter>
void ResourceHolder<Resource, Identifier>::load(Identifier ID, const std::string& filename, Parameter parameter)
{
std::unique_ptr<Resource> resourcePtr = std::make_unique<Resource>(new Resource());
if (!resourcePtr->loadFromFile(filename, parameter))
throw std::runtime_error("ResourceHolder - Failed to load file : " + filename);
auto inserted = mResourceMap.insert(std::make_pair(ID,std::move(resourcePtr))) ;
assert(!inserted.second && "ResourceHolder<Resource, Identifier>::load : function that takes 3 parameters");
}
template<typename Resource, typename Identifier>
Resource& ResourceHolder<Resource, Identifier>::get(Identifier ID)
{
auto found = mResourceMap.find(ID);
assert(found != mResourceMap.end() && "the given ID already exist in mResourceMap");
return found->second;
}
template<typename Resource, typename Identifier>
const Resource& ResourceHolder<Resource, Identifier>::get(Identifier ID) const
{
auto found = mResourceMap.find(ID);
assert(found != mResourceMap.end() && "the given ID already exist in mResourceMap");
return *found->second;
}
as for the error, it occurs when i declare a variable with ResourceHolder class .
ResourceHolder<sf::Texture,TextureID>
as for the enum it's declared in main.cpp as follow :
enum class TextureID{
Eagle,
};
Eagle,
};