Почему конструкторы с одинаковой сигнатурой валидные при использовании using? C++
Если мы хотим "унаследовать" конструкторы базового класса, то мы можем написать примерно так: using std::base_class::base_class. Я с таким подходом сделал такую структуру:
struct SharedHandle : std::shared_ptr<void> {
using std::shared_ptr<void>::shared_ptr;
};
Если я правильно понимаю принцип работы using, то из, например, родительского конструктора shared_ptr(void* ptr) создается конструктор дочернего класса подобного формата:
explicit SharedHandle(void* ptr)
: std::shared_ptr<void>::shared_ptr(ptr) {}
Это происходит неявно на этапе компиляции (поэтому слово "унаследовать" было написано в кавычках). Допустим, теперь я хочу сделать свой конструктор, принимающий void, но вызывающий другой конструктор базового класса, отличный от того, что вызывается при генерации из using. Получается такая структура:
struct SharedHandle : std::shared_ptr<void> {
using std::shared_ptr<void>::shared_ptr;
SharedHandle(void* ptr)
: std::shared_ptr<void>::shared_ptr(ptr, AnyDeleter) {}
// Тут мы вызываем конструктор shared_ptr(void*, Deleter)
// А не shared_ptr(void*), как это было бы при генерации из using
};
И отсюда вопрос: почему мне не выбивает ошибку об одинаковых сигнатурах конструктора, создаваемого из using, и конструктора, написанного мной. У них же одинаковая сигнатура. Или же компилятор во время сборки программы видит это и намеренно не генерирует из using "наследуемый" конструктор?
Ответы (1 шт):
См. здесь:
Using-declaration introduces a member of a base class into the derived class definition, such as to expose a protected member of base as public member of derived. In this case, nested-name-specifier must name a base class of the one being defined. If the name is the name of an overloaded member function of the base class, all base class member functions with that name are introduced. If the derived class already has a member with the same name, parameter list, and qualifications, the derived class member hides or overrides (doesn't conflict with) the member that is introduced from the base class.
(Выделено мной.)
Так что никакого конфликта нет и быть не должно...