Подтвердить что ты не робот

Компиляция Clang работает, а gcc не для наследования алмазов

Я не уверен, что здесь что-то не хватает, но кажется, что следующий код (аналогичный можно найти в другом ответе, который я больше не могу найти, вопрос здесь по-другому) компилирует отлично подходит для clang и не компилируется для gcc

#include <iostream>
using namespace std;

class base {
public:
 base(int i) {};

private:
 base(){};
};

class derivedA: virtual public base {
public:
 derivedA(int i) : base(i) {};

protected:
  derivedA() : base(0) {};
};

class derivedB: virtual public base {
public:
 derivedB(int i) : base(i) {};

protected:
  derivedB() : base(0) {};
};

class derivedAB : public derivedA, public derivedB {
public:
 derivedAB(int i) {};
 virtual ~derivedAB() = 0;
};

derivedAB::~derivedAB() {};

class lastDerived : public derivedAB {
public:
    lastDerived() : base(1), derivedAB(0) {};
};

int main(){
        lastDerived obj;
}

gcc сообщает

main.cpp: In constructor 'derivedAB::derivedAB(int)':
main.cpp:9:2: error: 'base::base()' is private
  base(){};

Какое правильное поведение? Я бы сказал, gcc, но я не уверен, почему.

4b9b3361

Ответ 1

Виртуальный базовый класс абстрактного класса не нужно инициализировать в mem-initializer-списке конструктора этого абстрактного базового класса.

Это обсуждается в 12.6.2p8:

[...] и сущность не является виртуальным базовым классом абстрактного класса [...]
[Примечание. Абстрактный класс (10.4) никогда не является самым производным классом, поэтому его конструкторы никогда не инициализируют виртуальные базовые классы, поэтому соответствующие mem-инициализаторы могут быть опущены. - конечная нота]

Итак, clang правильный, а gcc неверен. Это было бы иначе: derivedAB не абстрактно.


Это новое пособие в С++ 11, так как DR 257; g++ корректен для С++ 03. В https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19249 есть ошибка gcc; возможно, это может быть связано с выкапыванием.