首页 > 解决方案 > [temp.spec]/6 的起源故事?

问题描述

[temp.spec]/6 内容如下:

通常的访问检查规则不适用于显式实例化或显式特化声明中的名称,但出现在函数体、默认参数、基本子句、成员规范、枚举器列表或静态数据中的名称除外成员或变量模板初始化程序。[注意:特别是,函数声明器中使用的模板参数和名称(包括参数类型、返回类型和异常规范)可能是通常无法访问的私有类型或对象。——尾注]

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

标签: c++language-lawyertemplate-specializationaccess-controltemplate-instantiation

解决方案


添加此措辞是为了解决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

该问题表明措辞

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

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


推荐阅读