Нетипичное наследование шаблона от ошибки связывания шаблона - PullRequest
0 голосов
/ 10 июля 2019

У меня есть абстрактный класс DataFormatter в качестве интерфейса. У меня есть производный шаблон DataFormatterTemplate для разных типов данных. Здесь я переопределил чисто виртуальные функции и добавил специализацию для метода Process(). Теперь я хочу использовать типы данных INT, которые могут различаться по длине. Так что идея использовать один шаблон с нетиповыми параметрами INT<val>. Я хочу использовать производные от DataFormatterTemplate class DataFormatterTemplatePartial для своих специальных типов данных, и теперь я пытаюсь переопределить метод Process() для других val, но с неопределенной ошибкой ссылки.

В чем проблема?

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;
}

Ошибка связывания:

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()'

Как видите, компоновщик пытается найти Process() специализацию в базовом классе, но не хочет использовать производную.

1 Ответ

0 голосов
/ 11 июля 2019

Даже если вы не использовали Process() метод DataFormatterTemplate, вы должны дать ему определение или пометить его как чисто виртуальный.

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 */ }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...