模板指针参数包

template pointer parameter pack

本文关键字:参数 指针      更新时间:2023-10-16

为什么不能使用相同指针的偏移来实例化使用模板参数包的模板函数?

我的意思是:鉴于此简短代码,为什么我必须评论最后两行?

template <int * ... pt> void f() {}
int n[] = {1, 2, 3};
int m = n[1];
int main()
{
    f<n>();  // this is accepted
    f<n, &m>();  // this is accepted too
    //f<n, n+1>(); // this is not.
    //f<n, &n[1]>(); // this isn't accepted neither
}

n+1不代表与&m相同的地址?还是链接有区别?还是还有什么?

请参阅cppreference.com-模板非类型参数

  • 对于对象的指针,模板参数必须指定具有静态存储持续时间和链接(内部或外部(的对象的地址,或评估适当的null指针或STD :: NULLPTR_T值的常数表达式。

...

唯一的例外是参考和指针类型的非类型模板参数不能参考/是

的地址
  • 一个子对象(包括非静态类成员,基本子对象或数组元素(;
  • 一个临时对象(包括在参考初始化过程中创建的对象(;

因此不允许数组元素的地址。

在C 17中,来自[temp.arg.nontype]:

对于参考或指针类型的非类型模板参数,常数表达式的值不得指(或指针类型,不应是(:

的地址(
  • 一个子对象,
  • [...]

supObject是[Into.Object]:

对象可以包含其他称为子对象的对象。一个子对象可以是成员subobject([class.mem](,基类subobject([class.derdived](或数组元素。

使用&m作为非类型模板参数很好 - 它指向对象。该对象恰好是从n[1]初始化的,但这没关系。

另一方面,n+1&n[1]都指向数组n的元素,也就是说,它们都指向n的子对象,因此不允许使用。n+1&m无关。


在C 11和C 14中,措辞是包含性而不是独家,但结论是相同的:

a template-argument 对于非类型,非模板模板参数应为:

  • [...]
  • 一个常数表达式([expr.const](指定完整对象的地址带有静态存储持续时间,外部或内部链接或具有外部或内部链接的功能,包括功能模板和功能模板-ID,但不包括非静态类成员,以[...]
  • 表示(忽略括号(
  • [...]

允许使用m的指针,n[1]的指针不。