错误LNK2019:未解析的外部符号

时间:2014-05-07 13:41:51

标签: c++ unresolved-external

我需要你的帮助。我不知道代码有什么问题。 “Feature”是具有纯虚函数的模板基类,“AvgSentenceLength”是子类,但似乎在调用基类的“oneValueMap”函数时出现问题。错误是:

1>avgSentenceLength.obj : error LNK2019: unresolved external symbol "protected: class std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,double,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,double> > > __thiscall Feature<class Text>::oneValueMap(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,double)" (?oneValueMap@?$Feature@VText@@@@IAE?AV?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@NU?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@N@std@@@2@@std@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@N@Z) в функции "public: virtual class std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,double,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,double> > > __thiscall AvgSentenceLength::calculate(class Text)" (?calculate@AvgSentenceLength@@UAE?AV?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@NU?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@N@std@@@2@@std@@VText@@@Z)

feature.h中

#ifndef FEATURE_H   
#define FEATURE_H

#include <string>
#include <map>

using namespace std;

template <class T> class Feature
{
public:
    virtual map<string, double> calculate(T input) = 0;
protected:
    map<string, double> oneValueMap(string name, double value);
};

#endif FEATURE_H

feature.cpp

#include "feature.h"

template <class T> map<string, double> Feature<T>::oneValueMap(string name, double value)
{
    map<string, double> oneValueMap;

    oneValueMap.insert(pair<string, double>(name, value));

    return oneValueMap;
}

avgSentenceLength.h

#include "text.h"
#include "feature.h"

class AvgSentenceLength : public Feature<Text>
{
public:
    map<string, double> calculate(Text text);
};

avgSentenceLength.cpp

#include "avgSentenceLength.h"

map<string, double> AvgSentenceLength::calculate(Text text)
{
    double sum = 0.0;
    string name = "AvgSentenceLength";

    for (Sentence sentence: text.getText()) {
        for (Token word: sentence.getText()) {
            if (word.getType() == TokenType::tokenType::WORD) {
                sum = sum + 1;
            }
        }
    }

    return oneValueMap(name, sum / text.getLength()); //getLength() returns int
}

1 个答案:

答案 0 :(得分:3)

问题是您的Feature<Text>::opeValueMap()专业化没有定义。

这是因为专业化在avgSentenceLength.cpp,但定义在feature.cpp。它们是分开的编译单元,因此定义不能用于专业化。

一般来说,您应该将所有模板代码(事件定义为函数)放在.h文件中。

另一种选择,如果你知道将需要的所有特化,就是将代码的显式实例化添加到feature.cpp并让链接器完成它的工作:

template <class T> map<string, double> Feature<T>::oneValueMap(string name, double value)
{
    map<string, double> oneValueMap;

    oneValueMap.insert(pair<string, double>(name, value));

    return oneValueMap;
}

//explicit instantiations
template map<string, double> Feature<Text>::oneValueMap(string name, double value);
template map<string, double> Feature<Foo>::oneValueMap(string name, double value);
template map<string, double> Feature<Bar>::oneValueMap(string name, double value);