为什么数组类型不会衰减到类模板的指针
Why does array type not decay to pointer for class templates?
我们知道数组衰减到函数模板中的指针,并且要获取数组类型参数,我们需要使用对数组的引用来声明我们的函数模板:
template<class T, std::size_t N>
std::size_t number_of_elements(T (&ary)[N]) {
return N;
}
但是,为什么我们不需要在类模板中声明对数组参数的引用?下面的代码显示了这一点,并在 C++11 下编译。
template<class T>
struct cls_number_of_elements {};
template<class T, std::size_t R>
struct cls_number_of_elements<T[R]> {
static const int N = R;
};
char ary[] = "12345";
auto const N = cls_number_of_elements<decltype(ary)>::N;
char ar2[N];
您所说的"衰减"是从参数推断函数模板参数时发生的事情。 我在这里发布了更全面的解释。
为模板参数显式提供值时,没有扣除步骤;显式提供的值正是参数采用的值。
对于类模板,永远不会有参数推导;它们必须始终显式提供其参数。
说明性示例:
template<typename T> void f(T t) {}
template<typename T> struct S { void f(T t) {} };
...
int x[27];
f(x); // Type deduction: decay occurs, T = int *
f<int *>(x); // No deduction. T = int *
f<int[27]>(x); // No deduction. T = int[27]
S<int[27]>().f(x); // No deduction. T = int[27]
在后两种情况下,调整仍然发生。[temp.deduct]/3 明确重申了这一点:当 T
是数组类型时,函数参数 T t
表示t
具有指针类型,其方式完全相同:
void g(int t[27])
实际上指定t
具有类型 int *
。
来自 C++11 标准:
7.1.6.2 简单类型说明符
4
decltype(e)
表示的类型定义如下:— 如果
e
是无括号的 ID 表达式或无括号的类成员访问 (5.2.5(,则decltype(e)
是由e
命名的实体的类型。如果没有这样的实体,或者如果e
命名一组重载函数,则程序格式不正确;— 否则,如果
e
是 x值,则decltype(e)
T&&
,其中T
是e
的类型;— 否则,如果
e
是左值,则decltype(e)
T&
,其中T
是e
的类型;— 否则,
decltype(e)
是e
的类型。
鉴于
char ary[] = "12345";
decltype(ary)
表示ary
的类型(一个不带括号的 id 表达式(,即 char[6]
。
有关decltype
的更用户友好的描述,请参阅 http://en.cppreference.com。
在 C 和 C++ 标准之间,这个答案看起来解释是:
4.2 数组到指针的转换
- "
N
T
数组"或"未知T
界数组"类型的左值或右值可以转换为右值 类型为"指向T
的指针"。结果是指向数组的第一个元素的指针。
看起来这种转换确实发生在函数模板中推导的模板参数
number_of_elements(ary)
但不适用于类模板中的模板参数
cls_number_of_elements<char[5]>
和显式类型函数模板
number_of_elements<char[5]>(ary)
因为没有推断出这些类型。
查看代码,我有一个非常简短的解释,这与类和函数模板之间的差异没有任何关系:
对于number_of_elements
数组的"类型"是 T[N]
。示例适用于"类型"T[R]
cls_number_of_elements
。在这两种情况下,T
都会变得char
,而N
会恢复。 R
变得6
.需要&
的唯一原因是无法按值传递 c 数组。(见@bku_drytt的安瑟(
- 为什么这些函数不衰减到函数指针?
- 为什么多维数组中的空字符串文本衰减为空指针?
- 从原始指针(衰减的 C 样式数组)和大小生成范围::视图
- 数组变量衰减为指针
- 如果我只有指向第一个数组元素的指针,考虑到数组衰减,是否可以找到数组的长度?
- 在分配给指针到固定数组期间没有指针衰减
- 如果一个函数通过引用返回一个数组,它是指针的衰减吗?
- 推断衰减到函数指针的 lambda 类型
- 应该非捕获通用的lambdas衰减以发挥指针
- 数组衰减为指针和重载分辨率
- 运行时大小的数组和指针衰减
- 编译器在数组到指针衰减存储中生成的指针在哪里
- 为什么指针衰减优先于推导的模板
- 有没有办法避免数组到指针衰减
- 为什么数组类型不会衰减到类模板的指针
- 我能逆转数组到指针衰减的过程吗?
- 数组到指针衰减问题
- 为什么在模板函数中数组衰减为指针?
- 数组衰减为Lambda指针
- 如果通过模板函数中的 const 引用传递,数组不会衰减到指针