为什么数组类型不会衰减到类模板的指针?

时间:2015-11-16 05:44:32

标签: c++ c++11

我们知道arrays decay to pointers in function templates并且要获取数组类型参数,我们需要使用引用数组声明我们的函数模板:

Properties2

但是,为什么我们不需要在类模板中声明引用数组参数?下面的代码显示了这一点,并在C ++ 11下编译。

template<class T, std::size_t N>
std::size_t number_of_elements(T (&ary)[N]) {
  return N;
}

4 个答案:

答案 0 :(得分:2)

来自C ++ 11标准:

  

7.1.6.2简单类型说明符

     

4 decltype(e)表示的类型定义如下:

     

- 如果e是未加密码的 id-expression 或未加密码的类成员访问(5.2.5),decltype(e)e命名的实体的类型1}}。如果没有这样的实体,或者e命名了一组重载函数,那么该程序就是格式不正确的;

     

- 否则,如果e是xvalue,则decltype(e)T&&T的类型为e;

     

- 否则,如果e是左值,则decltype(e)T&T的类型为e;

     

- 否则,decltype(e)e的类型。

鉴于

char ary[] = "12345";

decltype(ary)表示ary(未加密码的 id-expression )的类型,即char[6]

decltype可以找到更加用户友好的<div class="grid" ui-grid="{data: roiTableData, columnDefs: roiCols, enableGridMenu: true, exporterCsvFilename: 'myFile.csv', enableSelectAll: true, onRegisterApi: gridApiFunc}" ui-grid-exporter></div> 说明。

答案 1 :(得分:2)

&#34;衰变&#34;你在谈论的是从参数中推导出一个函数模板参数时发生的事情。我发布了更全面的解释here

当您明确提供模板参数的值时,没有扣除步骤;您明确提供的值正是参数所需的值。

使用类模板,永远不会有参数推导;他们必须始终明确提供他们的参数。

说明性示例:

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 *

答案 2 :(得分:0)

在C和C ++标准与this answer之间,看起来好像是:

  

4.2数组到指针的转换

     
      
  1. 类型为“N T数组”或“T未知范围数组”的左值或右值可以转换为右值   类型为“T的指针。”结果是一个指向数组第一个元素的指针。
  2.   

对于功能模板

中推断出的模板参数,似乎会发生此转换
number_of_elements(ary)

用于类模板中的模板参数

cls_number_of_elements<char[5]>

和明确键入的函数模板

number_of_elements<char[5]>(ary)

因为没有推断出这些类型。

答案 3 :(得分:0)

查看代码我有一个非常简短的解释,它与类和函数模板之间的差异没有任何关系:

对于number_of_elements&#34;输入&#34;数组是T[N]。示例适用于cls_number_of_elements,其中&#34;类型&#34;是T[R]。 在这两种情况下,T将成为charN将成为R6变为&。 您需要- (void) tableView:(UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath { if(isFiltered) { Books *su = filteredTableData[indexPath.row]; passedSKU = su.sku; } else { // get the key from the cell that was selected from the list Books *selectedBook = [booksArray objectAtIndex:indexPath.row]; passedSKU = selectedBook.sku; } // programmatically set the tabBar index [self.tabBarController setSelectedIndex: 1]; 的唯一原因是因为您无法按值传递c数组。 (参见@bku_drytt的anser)