【临时规范】/6的起源故事

Origin story of [temp.spec]/6?

本文关键字:起源 故事      更新时间:2023-10-16

[temp.spec]/6读取:

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

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

添加该措辞是为了解决N0841中的6.40问题(自1996年起):

6.40明确说明显式实例化指令中的访问签入。

此问题及其解决方案来自Bill Gibbons的反射器发布c++std-ext-3258。
状态:打开
Bill Gibbon提出了无法显式实例化模板的问题,其中显式实例化指令的模板参数或其他组件引用了不可访问的类型。

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以来一直是规则。