我首先要指出这个问题纯粹是出于好奇 ,所以希望避免讨论,例如
"考虑远离
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并没有完全回答以上,据我所知)。
答案 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
}