1

可能重复:
为什么在使用模板时会出现“未解析的外部符号”错误?
对模板类函数的“未定义引用”

我在线出错:Console::getInstance()->readObjectData(a); 在 main.cpp

未定义的引用void Console::readObjectData<std::string>std::string&)

Console.h http://pastebin.com/WsQR7JNq

#define CONSOLE_H
#include <string>

using namespace std;

class Console
{
public:
    static Console* getInstance();


    template <typename T>
    void readObjectData(T& o);
protected:
private:
    Console();  // Private so that it can  not be called
    Console(Console const&);             // copy constructor is private
    Console& operator=(Console const&);  // assignment operator is private
    static Console* m_pInstance;


};
    #endif // CONSOLE_H

Console.cpp http://pastebin.com/N02HjgBw

#include "Console.h"
#include "Log.h"
#include <iostream>
#include <sstream>
#include <string>

using namespace std;

// Global static pointer used to ensure a single instance of the class.
Console* Console::m_pInstance = NULL;

Console::Console()
{

}

Console::Console(Console const&)
{

}

Console& Console::operator=(Console const&)
{

}

Console* Console::getInstance()
{
if (!m_pInstance)   // Only allow one instance of class to be generated.
    m_pInstance = new Console;

return m_pInstance;
}


template <typename T>
void Console::readObjectData(T& o) {
     //cin >> o;
}

main.cpp http://pastebin.com/U6qAJUN1

#include "Console.h"

using namespace std;

int main()
{

    string a;

    Console::getInstance()->readObjectData(a);
    return 0;
}

有任何想法吗?

4

6 回答 6

3

您不能在 .cpp 文件中定义模板<> 的函数。

移动

template <typename T>
void Console::readObjectData(T& o) {
     //cin >> o;
}

到头文件。

于 2012-10-08T17:37:39.480 回答
2

因为您没有将 readObjectData 的实现放在标头中,所以您需要提供该函数的显式特化 - 一个采用 std::string& 的函数。

这应该在 Console.cpp 中:

template <>
void Console::readObjectData(string& o) {
    //cin >> o;
}
于 2012-10-08T17:36:59.597 回答
2

你没有实现这个方法。您必须在 .h 文件中为您的模板提供实现

于 2012-10-08T17:36:17.827 回答
1

您不能将模板方法实现放入其中,Console.cpp它必须出现在头文件中,或者您必须为std::string.

于 2012-10-08T17:36:59.700 回答
0

在将一些 C++ 文件转换为输出(执行程序、共享库或...)的过程中,2 个工具将协同工作,首先是创建目标文件的编译器,然后是将这些对象转换为输出的链接器。您应该知道的是链接器与模板无关(除非在显式实例化的特殊情况下),模板将由编译器实例化,另一个注意事项是编译器与包含在该源文件中的每个源文件和头文件一起工作并忽略项目的所有其他文件。因此,当编译器想要编译main.cpp它时,看不到readObjectData因此它无法在目标文件中为该函数生成任何代码,并且当链接器想要链接对象以生成结果时,它将永远找不到该函数的实现!所以最简单的方法是将你的实现移动readObjectData.h文件中,每件事都会按预期工作。

于 2012-10-08T17:46:23.893 回答
0

模板化函数 (readObjectData) 的定义必须内联,而不是在 .cpp 文件中。当编译器看到带有模板化函数的类或模板化类时,它会复制整个类,其中包含新类型。因此,如果您将函数的定义粘贴在 .cpp 文件中,编译器将不知道实现在哪里,因为它不存在。

于 2012-10-08T17:38:05.733 回答