Полагаю, это ошибка компилятора MSVC 19.16.
Если вы напишите
class B : public A {
B(double) : A() {}
};
// ...
B b;
, вы должны получить ошибку от каждого компилятора, поскольку конструктор B(double)
удаляет значение по умолчанию B()
constructor.
Но, согласно этой странице (ищите "Наследование конструкторов")
Если объявление использования ссылается на конструктор прямой базыопределяемый класс (например, с использованием Base :: Base;), все конструкторы этой базы (игнорируя доступ к элементу) становятся видимыми для разрешения перегрузки при инициализации производного класса.
Если разрешение перегрузки выбирает унаследованный конструктор,он доступен, если он будет доступен, когда используется для создания объекта соответствующего базового класса: доступность введенного объявления using игнорируется.
Если при перегрузке разрешение перегрузки выбирает один из унаследованных конструкторов при инициализацииобъект такого производного класса, затем подобъект Base, из которого был унаследован конструкторited инициализируется с использованием унаследованного конструктора, а все остальные базы и члены Derived инициализируются так, как если бы использовался конструктор по умолчанию (по умолчанию используются инициализаторы членов по умолчанию, в противном случае происходит инициализация по умолчанию).Вся инициализация обрабатывается как один вызов функции: инициализация параметров унаследованного конструктора выполняется до инициализации любой базы или члена производного объекта.
Таким образом, в этом случае объявление using A::A;
должно преобразовать конструкторы A
в конструкторы B
.
Другой пример.
Определение B
только с конструктором, который получает std::string
,
class B : public A {
public:
using A::A;
B(std::string) : A() {}
};
должна быть возможна инициализация B
с целым числом
B b(1);
, потому что конструктор A(int)
наследуется какB
конструктор.