我有以下三个文件,其中找不到我正在产生的错误的来源:
Main.cpp
#include <SFML/Graphics.hpp>
#include <iostream>
#include "ResourceHolder.h"
namespace Textures
{
enum ID { Landscape, Airplane, Missile };
}
int main()
{
//...
try
{
ResourceHolder<sf::Texture, Textures::ID> textures;
textures.load(Textures::Airplane, "Airplane.png");
}
catch (std::runtime_error& e)
{
std::cout << "Exception: " << e.what() << std::endl;
}
//...
}
ResourceHolder.h
#pragma once
#include <map>
#include <string>
#include <memory>
#include <stdexcept>
#include <cassert>
template <typename Resource, typename Identifier>
class ResourceHolder
{
public:
void load(Identifier id, const std::string& fileName);
Resource& get(Identifier id);
const Resource& get(Identifier id) const;
private:
void insertResource(Identifier id, std::unique_ptr<Resource> resource);
std::map<Identifier, std::unique_ptr<Resource>> mResourceMap;
};
ResourceHolder.cpp
#include "ResourceHolder.h"
template <typename Resource, typename Identifier>
void ResourceHolder<Resource, Identifier>::load(Identifier id, const std::string& fileName)
{
//Create and load resource
std::unique_ptr<Resource> resource(new Resource());
if (!resource->loadFromFile(fileName)) {
throw std::runtime_error("ResourceHolder::load - Failed to load " + fileName);
}
//If loading was successful, insert resource to map
insertResource(id, std::move(resource));
}
template <typename Resource, typename Identifier>
Resource& ResourceHolder<Resource, Identifier>::get(Identifier id)
{
auto found = mResourcemap.find(id);
assert(found != mResourceMap.end());
return *found->second();
}
template <typename Resource, typename Identifier>
void ResourceHolder<Resource, Identifier>::insertResource(Identifier id, std::unique_ptr<Resource> resource)
{
//Insert and check success
auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource)));
assert(inserted.second);
}
如果要删除main.cpp中的try-catch组合,则代码可以正常编译;但是,如果我将其保留在此处,则会出现LNK2019(未解析的外部符号)错误。
此错误的根源是什么,我该如何解决?
最佳答案
您无法在.cpp文件中定义模板。必须在 header 中定义它们,以便编译器可以看到实现并生成特定的类。
这是一个更好的问题/答案,为什么它是如此Why can templates only be implemented in the header file?。
编辑: get
函数有什么问题
两件事情。
首先是这个auto found = mResourcemap.find(id);
。您的 map 名称不正确,m
应该是大写字母-> mResourceMap
。
然后一行return *found->second();
。映射迭代器包含一对,并且第一个和第二个成员不是函数,而是数据成员。您应该编写return *found->second;
。
我建议您在使用模板之前先了解要使用的结构。模板的编译错误非常凌乱且难以阅读。另外,您可以制作一个单独的测试程序,并制作一个没有模板的资源管理器,以更轻松地了解您的错误,然后在工作的资源管理器之上构建模板。
关于c++ - C++ SFML Gamedev书-ResourceHolder类中的未解析外部符号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31097562/