应用`const` CV-qualifier来衰减数组样式的`T arr []`函数参数(用于衰减为`T * const arr`)

时间:2017-06-04 13:39:30

标签: c++ arrays

我首先要指出这个问题纯粹是出于好奇 ,所以希望避免讨论,例如

  

"考虑远离new /动态数组,并使用适合用途的stdlib容器,例如: std::vector"

  

"为什么要首先使用int arr[]参数语法?我一直以为它被认为是令人困惑的可憎之一。"

将数组样式的函数参数衰减到T * const arr

如果我没有错,以下两个函数中的函数签名 - 意图用动态分配的C样式数组调用 - 由于衰减而相等,第一个参数是(显式或通过衰减)指向int的原始指针。

// A) mutable raw ptr to mutable elements
void foo(int * arr, unsigned n)
{
  // ...
  arr = nullptr; // legal
}

// B) mutable raw ptr to mutable elements
void foo(int arr[], unsigned n)
      /* decays to int * arr */
{
  // ...
  arr = nullptr; // legal
}

// ... used e.g. as
int * arr = new int[3]{1, 2, 3}; // c++11
foo(arr, 3);
delete[] arr;

现在,让我们说出于某种原因,我们希望原始指针(已经通过值传递给函数作为副本)是const指针(例如,为了正确性)。对于 A),这很简单:

// A') const raw ptr to mutable elements
void foo(int * const arr, unsigned n)
{
  arr = nullptr; // illegal, OK!
  // ...
}

对于 B)但是,我还没有能够执行此修改。

问题

  • 是否可以指定"数组类型"函数参数(用于动态数组参数)衰减到T * const arr

(我很高兴收到一个正确的重复目标来回答这个问题;我自己找不到一个。closest one I found并没有完全回答以上,据我所知)。

3 个答案:

答案 0 :(得分:4)

不,它不可能这样做,它将是无用的语法,并且由于顶层const和数组类型实际上都不是函数签名的一部分,它只会产生误导。

如果要将参数声明为不可修改的指针,请执行此操作。别写一些其他类型的东西会腐烂到不同的东西。

你仍然可以使用数组声明它,如果你认为有一些理由这样做,然后在定义中添加const:

// declaration
void foo(int arr[], unsigned n);

// definition
void foo(int * const arr, unsigned n)
{
  ...
}

答案 1 :(得分:3)

首先,您需要了解数组是指针不是一回事。 "衰变"你正在谈论的是对参数的转换:

  

在确定每个参数的类型之后,将任何类型为“T of T”或函数类型T的参数调整为“指向T的指针”。   生成参数类型列表后,在形成函数类型时,将删除修改参数类型的任何顶级cv限定符。

注意缺少" cv-qualifier-seq",这意味着将const数组转换为const指针(无论这意味着什么)都没有意义。

答案 2 :(得分:2)

对数组语法更加困惑:

using t_arrp = int *;

void foop(t_arrp const arr, unsigned n)
{
//  arr = nullptr; // illegal
}

using t_arr = int[];

void fooa(t_arr const arr, unsigned n)
{
    arr = nullptr; // fine
}