0

I have an abstract class DataFormatter as some interface. I have a derived template DataFormatterTemplate for different types of data. Here I have overried pure virtual functions and add specialisation for Process() method. Now I want to use data types INT that can differ in length. So the idea to use one template with non-type parameters INT<val>. I want to use derived from DataFormatterTemplate class DataFormatterTemplatePartial for my special data types and now I'm trying to override Process() method for different val, but having undefined reference error.

Whats the problem?

template<unsigned val>
struct INT {
    int data[val];
};

/**
 * Data formatter base class
 */
class DataFormatter {
public:
    DataFormatter() {};

    virtual ~DataFormatter() {};

    virtual void Process() = 0;
};

template<class OutFmt>
class DataFormatterTemplate : public DataFormatter {
public:
    virtual ~DataFormatterTemplate() {};

    virtual void Process();
};

template<>
void
DataFormatterTemplate<int>::Process() {}

template<unsigned filNum>
class DataFormatterTemplatePartial : public DataFormatterTemplate<INT<filNum>> {
public :
    virtual void Process();
};

template<unsigned filNum>
void DataFormatterTemplatePartial<filNum>::Process() {
    std::cout << filNum << std::endl;
}

int main() {
    DataFormatterTemplatePartial<4> df;
    DataFormatterTemplatePartial<3> df2;

    df.Process(); 
    df2.Process();

    return 0;
}

Linking error:

CMakeFiles/dft_test.dir/main.cpp.o:(.data.rel.ro._ZTV21DataFormatterTemplateI3INTILj3EEE[_ZTV21DataFormatterTemplateI3INTILj3EEE]+0x20): undefined reference to `DataFormatterTemplate<INT<3u> >::Process()'

CMakeFiles/dft_test.dir/main.cpp.o:(.data.rel.ro._ZTV21DataFormatterTemplateI3INTILj4EEE[_ZTV21DataFormatterTemplateI3INTILj4EEE]+0x20): undefined reference to `DataFormatterTemplate<INT<4u> >::Process()'

As you can see linker trying to find Process() specialization in base class, but don't want to use derived.

  • 1
    Possible duplicate of [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – drescherjm Jul 10 '19 at 17:35
  • @drescherjm has probably nailed the problem, but I can't be sure enough to hammer the question shut. Please provide a [mcve]. – user4581301 Jul 10 '19 at 18:18
  • @drescherjm, that is not the solution. Now I can reformulate the problem as "Why linker try to find specialization in `DataFormatterTemplate` class insted of derived `DataFormatterTemplatePartial`? I've editted the question with small example. – Aleksey Davydov Jul 11 '19 at 08:57

1 Answers1

0

Even though you haven't used the Process() method of DataFormatterTemplate you should give it a definition or mark it as pure virtual.

template<class OutFmt>
class DataFormatterTemplate : public DataFormatter {
public:
    virtual ~DataFormatterTemplate() {};

    virtual void Process() = 0;  //  <- should be pure virtual function
                                 //  Or virtual void Process() { /* default behavior */ }
};
ph3rin
  • 4,426
  • 1
  • 18
  • 42