实施CRTP模式

时间:2016-04-20 15:44:47

标签: c++ c++11

我试图实施CRTP模式,虽然非常接近,但却无法使其发挥作用。我的用例是我需要定义一堆类来执行查找以验证值。所有这些类基本上都是相同的,并且仅在它们构建查找值的文件中有所不同。对于给定的类类型,我想将查找信息存储在静态std :: set成员中(因为其中一些查找集非常大),这些成员在该类型的所有实例之间共享。对stackoverflow的研究使我将CRTP模式作为一种获得静态多态性的方法。这正是我需要的。

在下面的示例中,我有一个基本查找类(它本身派生自另一个类," CDE")。然后我定义了一个子类ICD9,它应该从文件" icd-9.txt中构建它的设置值。"我在一个更简单的文件中加入了这个概念,它的工作效果非常好。

问题在于,在编译时,我在链接过程中遇到了未解决的符号错误。我认为,有些东西与构造函数有关。我已经尝试了我能想到的ICD9构造函数的所有排列,但似乎无法弄明白。这与我的原型案例的部分区别在于我现在正在拆分头文件和实现文件,我怀疑我在语法上被绊倒了。

请注意,为了便于阅读,我从这些课程中删除了大量额外信息;我认为剩下的是对正在发生的事情的合理表述。

非常感谢任何帮助。感谢。

链接器错误:

Error   1   error LNK2019: unresolved external symbol "public: __thiscall LookupCDE<class ICD9>::LookupCDE<class ICD9>(void)" (??0?$LookupCDE@VICD9@@@@QAE@XZ) referenced in function "public: __thiscall ICD9::ICD9(void)" (??0ICD9@@QAE@XZ)

LookupCDE.h:

#include <set>
#include "CDE.h"

template <class T>
class LookupCDE : public CDE
{
    typedef std::set<string> lookup;

public:
    LookupCDE();

protected:
    static const char* filepath;
    static lookup data;

    string value;

    bool m1(char* s);
    int f1();
};

LookupCDE.cpp

#include <fstream>
#include "LookupCDE.h"

template<class T>
LookupCDE<T>::LookupCDE()
{
    ifstream file(filepath);
    while (getline(file, line))
        data.emplace(line);
    file.close();
}

template<class T>
bool LookupCDE<T>::m1(char* s)
{
    return data.count() > 0;
}

ICD9.h

#include "LookupCDE.h"

class ICD9 : public LookupCDE<ICD9>
{
public:
    ICD9();
};

ICD9.cpp

#include "ICD9.h"

ICD9::ICD9()
{

}

const char* LookupCDE<ICD9>::filepath = "Data/icd-9.txt";

1 个答案:

答案 0 :(得分:0)

您应该在类声明后将其添加到LookupCDE.h文件中:

template <class T>
class LookupCDE : public CDE
{
    // ...
};

// Add this 
template <class T>
typename LookupCDE<T>::lookup LookupCDE<T>::data;

LookupCDE.cpp中的任何其他定义也是如此。

或者将LookupCDE.cpp重命名为LookupCDE.tcc,在类声明后将其包含在LookupCDE.h中,并为data成员添加缺少的定义,如上所述。

有关使用.cpp执行模板类的原因无效的原因,请在marked duplicate中查看您的问题。