I have the goal to make a base class, and a CRTP subbase class containing a static vector
that will hold different values for each Derived class. However each object from the derived class must be able to see only one vector
for the entire class. Moreover, I need to manipulate this vector
through a common interface, this is why I am setting up a Base class.
Base class and subbase
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];
}
One of my derived classes:
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)
};
and its implementation:
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);
}
}
the problem occurs around this line
if(i>1) memory.push_back((long int)memory[i-1]+memory[i-2]);
compiler yells at me for
undefined reference to `subSeq<Fibonnacci>::memory'
this has been going on for hours, and since I am new to the concept CRTP, I see I don't understand it well and need help of people more capable than me.
Could someone enlighten me to what the problem is?
The member
Should be defined somewhere. To achieve your desired result, you should do this explicitly yourself in only a single translation unit (cpp file).
Or alternatively;
As some compilers do support common data folding (e.g COMDAT in msvc) which may help if you wish to use implicit instantiations, note this answer for more detail on common symbols.