Michael Kross
Michael Kross

Reputation: 47

C++ : Class templates, linker errors, and unresolved symbols

I've come across the following problem using templates (my IDE is Visual Studio 2012):

When I try to build my project, I get "unresolved external symbol" linker errors. I read that instead of separating my class between a header and source file, I should define everything in the header. However it still isn't working.

In the following example, I'm trying to create a class template for a "dictionary". It's supposed to pick up a type, and another type, and using two arrays create a "word" to "word" translation, if you'd use their common index. (Albeit "word" wouldn't be the exact description, I.E.: input[0] = 'A', output[0] = 2.5 -- this means the definition of 'A' is 2.5)

Here is my code:

#include <iostream>
using namespace std;
#ifndef WORD_H
#define WORD_H


template <class w, class d>
class Dictionary
{
public:

     Dictionary() ;//{}; // constructor (default)
    ~Dictionary() ;//{}; // destructor

    void Define(const w &st,const d &nd)
    {
        if(index < 100)
        {
            input[index] = st;
            output[index++] = nd;
        }
        else
        {
            cerr<<"Not enough space in dictionary.";
        }
    }// Define words using 2 parameters.st represents input, nd represents output (word -> translation)

    void print_words()
    {
        for(int i = 0; i < index ; i++)
        {
            cout<<index<<". "<<input[i]<<output[i]<<endl;
        }
    }

private:
    w input[100];
    d output[100];
    static int index;
};
template <class w, class d>
int Dictionary<w,d>::index = 0;
#endif

The 'main' file is simply:

#include "Word.h"
#include <iostream>

void main()
{
    Dictionary<int,double> a;
    a.Define(5,5.5);
}

And these are the errors:

1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Dictionary<int,double>::Dictionary<int,double>(void)" (??0?$Dictionary@HN@@QAE@XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Dictionary<int,double>::~Dictionary<int,double>(void)" (??1?$Dictionary@HN@@QAE@XZ) referenced in function _main

What should I do to fix my code?

Upvotes: 1

Views: 504

Answers (1)

BoBTFish
BoBTFish

Reputation: 19767

 Dictionary() ;//{}; // constructor (default)
~Dictionary() ;//{}; // destructor

You declare your default constructor and destructor, but do not define them. That is, you tell the compiler you are writing these functions, so it goes looking for them, but you actually have not written them, so it gets upset.

Your options are (basically all the same thing):

  • Remove these lines entirely, and get them generated by the compiler
  • Remove the first comment slashes, and use an empty definition (Dictionary(){}; // blah)
  • If you have a recent compiler (C++11 support), use the default keyword: Dictionary() = default;.

Also, in your header, all content of the file should be in the guards, (the include and the using). And I would strongly recommend you don't have using namespace std; in a header file (and I prefer never to use it at all). See Why is "using namespace std" considered bad practice?

Upvotes: 4

Related Questions