Компиляция 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, но я не уверен, почему.
Ответы
Ответ 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; возможно, это может быть связано с выкапыванием.