对<std :: string> std :: string&amp; </std :: string>的未定义引用

时间:2012-10-08 17:31:41

标签: c++

  

可能重复:
  Why do I get “unresolved external symbol” errors when using templates?
  “undefined reference” to a template class function

我在网上遇到错误:主控台:: getInstance() - &gt; 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;
}

任何想法?

6 个答案:

答案 0 :(得分:3)

您无法在.cpp文件中定义模板&lt;&gt;'d函数。

移动

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

到头文件。

答案 1 :(得分:2)

您没有实现此方法。您必须在.h文件

中提供模板的实现

答案 2 :(得分:2)

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

的函数。

这应该在Console.cpp中进行:

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

答案 3 :(得分:1)

您无法将模板方法实施放在Console.cpp中,它必须出现在头文件中,或者您必须为std::string实现明确的专业化。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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