[英]template pointer parameter pack
为什么带有模板参数包指针的模板函数无法使用相同指针的偏移量进行实例化?
我的意思是:给出这个简短的代码为什么我必须注释掉最后两行?
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
相同的地址吗? 或者链接有什么不同? 还有什么?
- 对于指向对象的指针,模板参数必须指定具有静态存储持续时间和链接(内部或外部)的对象的地址,或者计算为适当的空指针或std :: nullptr_t值的常量表达式。
...
唯一的例外是引用和指针类型的非类型模板参数不能引用/是地址
- 子对象(包括非静态类成员,基础子对象或数组元素);
- 临时对象(包括在引用初始化期间创建的对象);
所以不允许数组元素的地址。
在C ++ 17中,来自[temp.arg.nontype] :
对于引用或指针类型的非类型模板参数,常量表达式的值不应引用(或者对于指针类型,不应该是地址):
- 一个子对象,
- [...]
子对象的位置,来自[intro.object] :
对象可以包含其他对象,称为子对象。 子对象可以是成员子对象([class.mem]),基类子对象([class.derived])或数组元素。
使用&m
作为非类型模板参数很好 - 它指向一个对象。 该对象碰巧是从n[1]
初始化的,但这并不重要。
另一方面, n+1
和&n[1]
都指向数组n
的元素,也就是说它们都指向n
的子对象,因此这是不允许的。 n+1
和&m
无关。
在C ++ 11和C ++ 14中 ,措辞是包容性的而不是排他性的 ,但结论是相同的:
模板参数的用于非类型的,非模板的模板参数应是以下之一:
- [...]
- 一个常量表达式([expr.const]),用于指定具有静态存储持续时间和外部或内部链接的完整对象的地址,或具有外部或内部链接的函数,包括函数模板和函数模板ID,但不包括非静态类成员,表达(忽略括号)为[...]
- [...]
允许指向m
的指针,指向n[1]
的指针不是。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.