Документация Clang аккуратно объясняет, что
Если класс или структура не имеет пользовательского конструктора по умолчанию, С++ не позволяет вам по умолчанию построить экземпляр const, как это ([dcl.init], p9)
Следующий код имеет такой пользовательский конструктор по умолчанию для Base
, но g++ и Clang не согласны с тем, является ли конструктор по умолчанию для Derived
определяемым пользователем, хотя Derived
явно наследует все Base
конструкторы (используя конструкцию новых конструкторов наследования С++ 11)
#include <iostream>
class Base
{
public:
Base(): b_(0) {} // look! user-defined default constructor
void print() const { std::cout << b_ << "\n"; }
private:
int b_;
};
class Derived
:
public Base
{
using Base::Base; // does this constitute a user-defined default constructor?
};
int main()
{
Base const b;
b.print(); // 0 for g++ & CLang
Derived const d;
d.print(); // 0 for g++, Clang: "default initialization of an object of const type 'const Derived' requires a user-provided default constructor"
}
g++ 4.8 с радостью принимает этот код, но Clang 3.3 этого не делает. Что говорит стандарт?
ПРИМЕЧАНИЕ: без пользовательского конструктора по умолчанию для Base
, ни g++ 4.8, ни Clang 3.3 не принимают Base const b;
(тогда как, например, g++ 4.7.2 ранее принимал это). Учитывая, что g++ знает о правиле, я думаю, что это означает, что g++ рассматривает конструктор по умолчанию для Derived
как определяемый пользователем. Но Clang 3.3 думает иначе.
UPDATE: на основе ответа @JesseGood, что конструкторы аргументов 0/1 никогда не наследуются, я попытался изменить конструктор Base
на
Base(int b = 0, void* = nullptr): b_(b) {}
но он не разрешает ошибку Clang.