对 c++ (g++) 中具有菱形继承的函数的未定义引用

Undefined reference to function in c++ (g++) with diamond inheritance

本文关键字:继承 函数 引用 未定义 c++ g++      更新时间:2023-10-16

我简化了我的原始问题以突出问题,因此某些灯具可能看起来是多余的,但它们对我项目的其余部分很有用。

此示例的代码位于单个文件中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++ 上重现
  • 按此处删除模板可消除错误。

找到了一个解决方案并将其发布在这里以供将来参考。在DataOp中添加this可以解决问题:

template<typename T> struct DataOp: virtual Data<T> {
    virtual T value() { return this->data(); }
};