Я столкнулся с очень неприятной ошибкой сегодня, вот MWE:
#include <iostream>
class X {
public:
X() { std::cout << "Default" << std::endl; }
X(int a) { std::cout << a << std::endl; }
};
class Y : public X { };
class Z : public Y {
using X::X;
};
int main() {
Z instance{3};
}
Вопреки моим ожиданиям «Default
«печатается. Следует признать, что код неисправен, потому что унаследованные конструкторы Z
попытаться инициализировать X
без указания того, как построить Y
(*). Но все же, не должен ли компилятор жаловаться? Каково обоснование конструктора по умолчанию Y
(и впоследствии X
) вызывается, полностью молча игнорируя мой параметр 3
? Это задокументировано где-то в стандарте? Или это ошибка в моем компиляторе?
Моя среда gcc version 6.2.1 20160916 (Red Hat 6.2.1-2)
, Предупреждение компилятора не выдается даже при -Weffc++ -Wall -Wextra -pedantic
,
Это ошибка g ++, код неверный. Только конструкторы из прямых баз могут быть унаследованы:
[Namespace.udecl] §3 Если такой используя декларирование называет конструктор вложенное имя спецификатор должен назвать прямой базовый класс определяемого класса
Других решений пока нет …