模板方法中未解析的外部符号

时间:2013-05-17 07:18:16

标签: c++ templates methods lnk2019

如果没有发布大量代码,我会解释这个问题有点复杂,但我会尽我所能。我正在编写一个游戏内控制台,它要求我将正常的自由函数和实例方法绑定到控制台,以便可以使用简单的关键字调用它们。控制台可以绑定的每个方法/函数都需要一个sf :: String参数,并返回一个sf :: String。 (我在游戏中使用SFML,而sf是SFML的命名空间)

[注意:所有4个类(Console,CFunctionInterface,CFunction和CMethod)都在同一个文件(console.h)中声明。他们的成员都在一个文件(console.cpp)中定义。

要设置它,我有1个父(CFunctionInterface)和2个子(CFunction,CMethod)'容器'类。父母在其中有一个公共方法。

sf::String call(sf::String p_Value);

CFunction的声明如下:

class CFunction : public CFunctionInterface
{
public:
    typedef sf::String (*FFP)(sf::String);  //free function pointer type

    CFunction(const FFP p_Function);
    sf::String call(const sf::String p_Value);
private:
    FFP m_Function;
};

CMethod的声明如下:

template <typename ClassType>
class CMethod : public CFunctionInterface
{
public:
    typedef sf::String (ClassType::*MFP)(sf::String);   //member function pointer type

    CMethod(const ClassType* p_Instance, const MFP p_Function);
    sf::String call(const sf::String p_Value);
private:
    ClassType* m_Instance;
    MFP m_Function;
};

一切都是非常自我解释的,我相信你可以想象call()对每个类的作用。

回到控制台,我有一个

std::multimap <string, CFunctionInterface* > 

设置存储所有函数指针。当我想调用一个函数时,将迭代此映射,如果输入函数名称与其中一个键匹配,则将调用该键的值。例如(name是所需函数的所需键,param是我要传递给函数的sf :: String [push_back()是一个向控制台输出消息的控制台方法]):

for(auto iter = functions.begin(); iter!= functions.end(); iter++)
{
    if(iter->first == name)
    {
        push_back(iter->second->call(param));
        return;
    }
}
push_back("Error! Function with name: " + name + " not found!");

现在我在控制台内部有一些方法,用于绑定和取消绑定函数。这就是出现问题的地方。

template <typename ClassType>
void bindFunction(const string name, const ClassType* instance, sf::String (ClassType::*func)(sf::String));
void bindFunction(const string name, sf::String (*func)(sf::String));
void unbindFunction(const string name);

最后两个功能很漂亮。没有问题。但这是模板混蛋。 这是他的定义(在console.cpp中):

template <typename ClassType>
void CConsole::bindFunction(const string name, const ClassType* instance, sf::String    (ClassType::*func)(sf::String))
{
    //Checks to see if name is already in use
    for(auto iter =  functions.begin(); iter != functions.end(); iter++)
    {
        if(iter->first == name)
        {
            push_back("Error! Attempting to bind function. The name \'" + name + "\' is already in use!");
            return;
        }
    }
    //Everything checks out
    CMethod* temp = new CMethod<ClassType> (instance, func);
    functions.insert( pair<string, CFunctionInterface* > (name, temp) );
}

当我在整个程序中根本不打电话给他时,它编译并运行得很好。但是当我试着打电话的时候;我收到这个错误:

1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall CConsole::bindFunction<class CDog>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class CDog const *,class sf::String (__thiscall CDog::*)(class sf::String))" (??$bindFunction@VCDog@@@CConsole@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PBVCDog@@P83@AE?AVString@sf@@V45@@Z@Z) referenced in function _main
1>S:\Users\Logan\documents\visual studio 2012\Projects\newConsole\Debug\newConsole.exe : fatal error LNK1120: 1 unresolved externals

这就是在'int main()'中调用它的方式:

CDog* rex = new CDog;
console->bindFunction<CDog>("bark", rex, &CDog::bark);

CDog只是一个带有公共bark()方法的简单类,返回“Woof!”。 控制台正在main中创建,并且只是指向新CConsole对象的指针。 包含“console.h”,并且没有#include循环。我查过了。

我在线做了一些googleing,但我从来没有发现像这样的链接器错误。它总是忘记包含或包含循环。

有谁知道我做错了什么,以及如何解决?感谢您抽出宝贵时间阅读本文,并提前感谢您的回复。 - 洛根

0 个答案:

没有答案