История происхождения [temp.spec]/6?

[temp.spec]/6 читает:

Обычные правила проверки доступа не применяются к именам в объявлении явной реализации или явной специализации, за исключением имен, появляющихся в теле функции, аргумент по умолчанию, базовое предложение, спецификация члена, список перечислителя или статические данные. инициализатор шаблона элемента или переменной. [Примечание: В частности, аргументы и имена шаблонов, используемые в деклараторе функции (включая типы параметров, типы возвращаемых данных и спецификации исключений), могут быть закрытыми типами или объектами, которые обычно недоступны. - конец примечания]

Какова была мотивация этого правила? Какое предложение внесло его (или оно древнее?) И для чего?

1 ответ

Решение

Эта формулировка была добавлена ​​к решению проблемы 6.40 из N0841 (с 1996 года):

6.40 Разъяснение регистрации доступа в явных директивах создания экземпляров.

Эта проблема и ее решение взяты из публикации рефлектора Билла Гиббонса C++std-ext-3258.
Статус: открыт
Билл Гиббонс поднял вопрос о том, что невозможно явно создавать экземпляры шаблонов, в которых аргументы шаблона или другие компоненты явных директив создания экземпляров ссылаются на недоступные типы.

namespace N {
  template <class T> void f(T);
}
namespace M {
  class A {
    class B {};
    void f() {
      B b;
      N::f(b);
    }
  };
}
template void N::f(M::A::B); // should be allowed

Вопрос предлагает формулировку

Обычные правила проверки доступа не применяются к явным экземплярам. В частности, аргументы шаблона и имена, используемые в деклараторе функции (например, включая типы параметров, типы возвращаемых данных и спецификации исключений), могут быть закрытыми типами или объектами, которые обычно недоступны, а шаблон может быть шаблоном или элементом-членом. функция, которая обычно не была бы доступна.

Который был тогда принят как часть N0892, и был правилом с C++98.