Почему компилятор выбирает конструктор базового класса в списке аргументов шаблона? - PullRequest
13 голосов
/ 10 февраля 2012

Дополнительный вопрос к этому .

В основном, в следующем коде, почему компилятор считает, что B внутри A<B> в C s конструктореобратитесь к (недоступному) конструктору базового класса B?

struct B{};

template <typename T>
struct A : private T{};

struct C : public A<B>{                                                                             
    C(A<B>);   // ERROR HERE
};

Живой пример на Ideone. Вывод:

prog.cpp:1: 9: ошибка: «struct BB :: B» недоступна
prog.cpp: 7: 7: ошибка: в этом контексте

Обратите внимание, что такая же ошибка появляется при измененииаргумент конструктора для A<B*>, A<B&> или даже A<const B>.Также обратите внимание, что три из MSVC10, GCC 4.7 и Clang 3.1 ToT будут давать ошибку, поэтому это должно быть что-то в спецификации C ++. Что это?

1 Ответ

15 голосов
/ 10 февраля 2012

Стандарт позволяет вводить имена классов, которые будут менее доступны, чем исходные имена.Это даже упоминается в примечании в §11.1 / 5 вместе с примером:

[ Примечание: В производном классе поиск имени базового класса найдетимя введенного класса вместо имени базового класса в области, в которой он был объявлен.Имя введенного класса может быть менее доступным, чем имя базового класса в области, в которой оно было объявлено. - конечная запись ]

[ Пример :

class A { };
class B : private A { };
class C : public B {
  A *p; // error: injected-class-name A is inaccessible
  ::A *q; // OK
};

- конец примера ]

При доступе к A без квалификации используется введенное имя, которое недоступно, поскольку оно происходит из частного наследования.Для доступа к квалифицированному A используется объявленное имя, которое доступно в глобальной области.

...