Наследование общественных / защищенных / частных конструкторов - PullRequest
2 голосов
/ 03 апреля 2019

Если я правильно понимаю:

class Base { /*...*/ };
class Derived: public Base { public: using Base::Base; }

обеспечит наследование всех Base конструкторов в Derived.

Но как насчет открытых / защищенных / частных конструкторов?

class Base {
    friend void g();
public:
    Base (A a);
protected:
    Base (B b);
private:
    Base (C c);
};

class Derived: public Base {
public:
    using Derived::Derived;
};

Я не могу найти никакой спецификации по этому вопросу, но я попробовал следующее:

void f () {
    Derived{A{}}; // OK
    Derived{B{}}; // Inaccessible
    Derived{C{}}; // Inaccessible
}

void g () {
    Derived{A{}}; // OK
    Derived{B{}}; // OK
    Derived{C{}}; // OK
}

Так что, похоже, using Base::Base не принимает во внимание модификаторы доступа при принятии решениякакие конструкторы наследовать (он наследует приватный), но наследует их с этими модификаторами (приватные / защищенные остаются недоступными для других), и он разрешает закрытый / защищенный доступ друзьям Base (дружба не наследуется, поэтому g не является другом Derived, но он все еще может получить доступ к закрытому / защищенному конструктору Derived, унаследованному от Base).

Это правильное и стандартное поведение?

1 Ответ

1 голос
/ 03 апреля 2019

Спецификация, которую вы ищете, находится в [namespace.udecl] ¶19 , выделено мое.

A using-декларатор , который именует конструктор, не создает синоним; Вместо этого дополнительные конструкторы доступны, если они были бы доступны при использовании для создания объекта соответствующей базы. класс , а доступность декларации использования игнорируется.

Ваше тестирование соответствует этому параграфу. Проверка доступности завершается неудачно или проходит точно так же, как при создании Base в проверяемых областях.

...