[temp.spec]/6的起源故事?

And*_*zos 5 c++ access-control template-specialization language-lawyer template-instantiation

[temp.spec]/6读取:

通常的访问检查规则并不适用于名称在显式实例或明确专门的声明,与出现在函数体中,默认参数,基本条款,成员规格,枚举列表,或静态数据的名称除外成员或变量模板初始化程序.[注意:特别是,函数声明符中使用的模板参数和名称(包括参数类型,返回类型和异常规范)可能是通常无法访问的私有类型或对象. - 结束说明]

这条规则背后的动机是什么?哪个提案引入了它(或者它是古老的?),为什么?

Bar*_*rry 8

增加了这一措辞,以解决N0841(1996年)的问题6.40 :

6.40明确实例化指令中访问签入的说明.

这个问题及其解决方案来自Bill Gibbons的反馈贴c ++ std-ext-3258.
状态:打开
Bill Gibbons提出的问题是,无法显式实例化模板参数或显式实例化指令的其他组件引用不可访问的类型的模板.

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
Run Code Online (Sandbox Code Playgroud)

问题表明措辞

通常的访问检查规则不适用于显式实例化.特别是,模板参数和名称在函数声明中使用(例如,包括参数类型,返回类型和异常规格)可以是私有的类型或对象,这通常不能访问和模板可以为成员模板或成员通常无法访问的功能.

然后将其作为N0892的一部分采用,并且自C++ 98以来一直是规则.

  • 另见http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0692r1.html (2认同)