1

Possible Duplicate:
Why do I get “unresolved external symbol” errors when using templates?
“undefined reference” to a template class function

I got error on line: Console::getInstance()->readObjectData(a); in main.cpp

undefined reference to 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;
}

any ideas?

Community
  • 1
  • 1
Palaima
  • 331
  • 7
  • 17
  • 2
    Compiler needs to see the definition of template function, You need to include the definition in your header file. – Alok Save Oct 08 '12 at 17:36
  • Each and every day, there is a new question about templates and undefined references... – jpalecek Oct 08 '12 at 17:39

6 Answers6

3

You cannot define template<>'d function in .cpp file.

Move

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

To header file.

Mislav Blažević
  • 268
  • 1
  • 3
  • 9
2

You did not implemented this method. You have to provide implementation for your template in .h file

Kylo
  • 2,300
  • 1
  • 19
  • 24
2

Because you've not put the implementation of readObjectData in the header, you will need to provide an explicit specialization of the function - one that takes std::string&.

This should go in Console.cpp:

template <>
void Console::readObjectData(string& o) {
    //cin >> o;
}
Graham Perks
  • 23,007
  • 8
  • 61
  • 83
1

You cannot place your template method implementation in Console.cpp it must appear in the header file, or you must implement an explicit specialization for std::string.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
0

The definition for the templated function (readObjectData) has to be inlined, not in a .cpp file. The compiler when it see's a class with a templated function, or a templated class, makes a copy of the entire class with the new type stuck in there. So if you stick the definition of the function in the .cpp file, the compiler will not know where the implementation is because it doesn't exist.

C.J.
  • 15,637
  • 9
  • 61
  • 77
0

In the process of converting some C++ files to the output( executive, shared library or ... ) 2 tools will co-operate, first compiler that create object files and then linker that convert those objects to the output. What you should know is that linker has nothing to do with template( except in special case of explicit instantiation ), and templates will be instantiated by compiler and another note is compiler work with each source files and headers that included in that source file and ignore all other files of your project. So when compiler want to compile main.cpp it see no implementation of readObjectData and thus it can't generate any code in the object files for that function, and when linker want to link objects to result it will never find an implementation for that function! So the easiest way is to move your implementation of readObjectData to the .h file and every thing will work as expected.

BigBoss
  • 6,904
  • 2
  • 23
  • 38