Почему нельзя сделать унаследованный защищенный конструктор publi c? - PullRequest
16 голосов
/ 30 мая 2020

Учтите:

class A
{
protected:
    A(int) {}
    void f(int) {}

public:
    A() {}
};

class B : public A
{
public:
    using A::A;
    using A::f;
};

int main()
{
    B().f(1); // ok
    B(1); // error: 'A::A(int)' is protected within this context
}

Почему нельзя создать унаследованный protected конструктор public, а унаследованную protected функцию-член можно?

Ответы [ 2 ]

10 голосов
/ 30 мая 2020

В отличие от других членов, доступность объявления-использования, которое представило унаследованный конструктор , игнорируется.

[namespace.udecl] / 19 ,

(выделено мной)

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

3 голосов
/ 30 мая 2020

Фактически, унаследованный конструктор может быть опубликован c, но не только так, как вы его написали. Вы можете определить свой класс B следующим образом:

class B : public A {
public:
    B() {}

    B(int x) : A(x) {}  // instead of using A::A(int)
    using A::f;
};

(см. Его на GodBolt )

Возможно, стандартный комитет решил, что выражение using A::A будет немного двусмысленно, поскольку конструктор базового класса - это не совсем то же самое, что конструктор подкласса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...