C ++:类模板,链接器错误和未解析的符号

时间:2014-01-03 12:17:11

标签: c++ templates linker-errors

我使用模板遇到了以下问题(我的IDE是Visual Studio 2012):

当我尝试构建我的项目时,我得到“未解析的外部符号”链接器错误。我读到它而不是在标题和源文件之间分离我的类,我应该在标题中定义所有内容。但它仍然无效。

在下面的示例中,我正在尝试为“词典”创建一个类模板。如果您使用它们的公共索引,它应该选择一种类型和另一种类型,并使用两个数组创建“单词”到“单词”翻译。 (虽然“单词”不是确切的描述,I.E。:输入[0] ='A',输出[0] = 2.5 - 这意味着'A'的定义是2.5)

这是我的代码:

#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

'main'文件只是:

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

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

这些是错误:

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

我该怎么做才能修复我的代码?

1 个答案:

答案 0 :(得分:4)

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

声明您的默认构造函数和析构函数,但不要定义它们。 也就是说,你告诉编译器你正在编写这些函数,所以它会去寻找它们,但你实际上已经写了它们,所以它会感到沮丧。

你的选择(基本上都是一样的):

  • 完全删除这些行,并由编译器生成它们
  • 删除第一个注释斜杠,并使用空定义(Dictionary(){}; // blah
  • 如果您有最新的编译器(C ++ 11支持),请使用default关键字:Dictionary() = default;

此外,在您的标头中,文件的所有内容应该在警卫中(includeusing)。我强烈建议你在头文件中没有using namespace std;(我宁愿永远不要使用它)。见Why is "using namespace std" considered bad practice?