【问题标题】:Implementing CRTP and issue with "undefined reference"实施 CRTP 并出现“未定义的引用”
【发布时间】:2014-11-15 20:16:49
【问题描述】:

我的目标是创建一个基类和一个包含static vector 的 CRTP 子基类,它将为每个派生类保存不同的值。但是,派生类中的每个对象都必须只能看到整个类的一个 vector。而且,我需要通过一个通用接口来操作这个vector,这就是我设置一个Base类的原因。

基类和子基类

class Seq {
public:
    virtual unsigned long int elem(int i) = 0;
    virtual void print(ostream& os) =0; // print out to a ostream
    virtual int length() const =0;// return size of vector
    virtual ~Seq() {}
protected:
    virtual void gen_elems(int i) = 0; //generates elements
};

template<class T>
class subSeq: public Seq {
public:
    unsigned long int elem(int i);
    void print(ostream& os);
    int length() const {return (int)memory.size();}
    virtual ~subSeq() {}
protected:
    static vector<long int> memory;
    virtual void gen_elems(int i) = 0;
};

template<class T>
void subSeq<T>::print(ostream& os) {
    if((int)memory.size() != 0) {
        cout << "Stored numbers: ";
        for(int i=0; i<(int)memory.size(); i++) {
            os << memory[i] << " ";
        }
        cout << "\n";
    } else {
        cout << "Empty class!!\n";
    }
}

template<class T>
unsigned long int subSeq<T>::elem(int i) {
    if( i>=(int)memory.size() ) gen_elems(i);
    return memory[i];
}

我的一个派生类:

class Fibonnacci: public subSeq<Fibonnacci> {
public:
    Fibonnacci(int=0);
    ~Fibonnacci() {}
protected:
    void gen_elems(int i); // Gera os elementos da série até o iésimo elemento (protected)
};

及其实现:

Fibonnacci::Fibonnacci(int param) { if(param) gen_elems(param); }

void Fibonnacci::gen_elems(int param) {

    for(int i=(int)memory.size(); i<param; i++) {
        if(i>1) memory.push_back((long int)memory[i-1]+memory[i-2]);
        else memory.push_back(1);
    }

}

问题出现在这条线附近

if(i>1) memory.push_back((long int)memory[i-1]+memory[i-2]);

编译器对我大喊大叫

undefined reference to `subSeq<Fibonnacci>::memory'

这已经持续了几个小时,由于我对 CRTP 概念不熟悉,我发现我不太了解它,需要比我更有能力的人的帮助。

谁能告诉我问题出在哪里?

【问题讨论】:

  • 更新:如果我从 CRTP 中删除静态,一切正常,但是每个派生类对象都会有自己的向量内存,这打破了我的目标
  • 成员template&lt;&gt; vector&lt;long int&gt; subSeq&lt;Fibonnacci&gt;::memory; 应该在某个地方定义。为了达到您想要的结果,您应该只在一个翻译单元(cpp 文件)中自己明确地执行此操作。如果您希望使用隐式实例化,请注意此答案以获取有关常见符号的更多详细信息stackoverflow.com/a/16005504/3747990
  • 酷!模板 vector subSeq::memory = {};工作正常,看来我达到了结果。我很不确定如何定义向量,但它有效。你会添加评论作为答案还是我应该这样做?
  • 尝试使用(类型名内存)?它会告诉编译器内存确实存在。
  • 使用 typename 我不必在其他地方定义静态变量?

标签: c++ vector static crtp


【解决方案1】:

会员

template <>
vector<long int> subSeq<Fibonnacci>::memory;

应该在某个地方定义。为了达到您想要的结果,您应该只在一个翻译单元(cpp 文件)中自己明确地执行此操作。

或者;

template <class T>
vector<long int> subSeq<T>::memory = {};

由于某些编译器确实支持通用数据折叠(例如 msvc 中的 COMDAT),如果您希望使用隐式实例化可能会有所帮助,请注意此 answer for more detail on common symbols

【讨论】:

  • 感谢您的编辑。我不是以英语为母语的人,有时我会犯如此可怕的错误。另外,我仍然掌握使用堆栈溢出的窍门。
  • @GChamon,没问题。你的问题有一个很好的转折
猜你喜欢
  • 2016-08-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 2021-09-07
  • 1970-01-01
  • 2013-04-30
  • 2021-09-01
  • 2021-10-30
相关资源
最近更新 更多