Я упростил исходную проблему, чтобы выделить ее, поэтому некоторые приборы могут выглядеть излишними, но они полезны для остальной части моего проекта.
Код этого образца находится в одном файле t.cc
и скомпилирован с g++ t.cc
с ошибкой:
In function `DataOp<int>::value()':
t.cc:(.text._ZN6DataOpIiE5valueEv[_ZN6DataOpIiE5valueEv]+0x28): undefined reference to `Data<int>::data() const'
collect2: error: ld returned 1 exit status
Код такой:
template<typename T> struct Data {
virtual int data() const = 0;
};
template<typename T> struct DataImpl: virtual Data<T> {
virtual int data() const override { return 0; }
};
template<typename T> struct DataOp: virtual Data<T> {
virtual T value() { return Data<T>::data(); }
};
struct OpImpl
: DataOp<int>
, DataImpl<int>
{};
int main() {
OpImpl c;
return 0;
}
Интересно, что удаление virtual
в реализации DataOp
устраняет проблему компоновщика (но я не могу сделать это легко в проекте).
Обновление
- Ссылка для воспроизведения результатов.
- Проблема возникает, когда оптимизация отключена, например, когда -O0 (или без флага оптимизации) предоставляется g ++.
- Кажется также воспроизводимым на Clang ++
- Удаление шаблонов как здесь устраняет ошибку.