问题与错误消息所描述的完全一样:float& ap[]
声明了一个引用数组,这不是 C++ 中的合法类型,就像禁止引用的指针和引用的引用一样。
如果它是合法的,您可以通过考虑指针数组来思考它的含义。引用在某些方面在概念上类似于指针。引用旨在引用另一个实体,当引用需要运行时表示时,C++ 实现通常使用指针。
因此,如果要将指针数组传递给函数,则需要构造一个初始化它:
float a, b, c;
float *arr[] = {&a, &b, &c}; // or in fictional array-of-references syntax: float &arr[] = {a, b, c};
或者,如果您已经有一个浮点数组,并且您想要一个指向这些元素的指针数组:
float a[3];
float *b[] = {&a[0], &a[1], &a[2]); // or in fictional array-of-references syntax: float &b[] = {a[0], a[1], a[2]};
大概您真正想要的是通过引用将数组传递给函数,以便函数可以写入数组并且调用者可以看到更改。(或者仅仅是因为你想避免复制数组)。由于通常函数参数是按值传递的,而通过引用传递的方法是坚持&
在那里,你对数组类型也做了同样的事情。这是一个很好的直觉,但是 C++ 中有一些皱纹让你搞砸了。
第一个是 C++ 中声明的奇怪语法。您可以在其他地方阅读有关“螺旋规则”或“声明模仿使用”的信息,但只要说它是否&
“更接近”(在语法上)变量名或float
. float &arr[]
是一个引用数组。您需要几个括号来将 & 符号更靠近变量:float (&arr)[]
声明对数组的引用。
接下来是 C++ 不幸地从 C 继承了一些奇怪的行为,旨在使数组和指针几乎可以互换。您的情况下的相关行为是,如果您声明一个采用数组参数的函数:
void foo(int arr[], int size);
该语言明确表示该类型被“调整”为指针。结果与以下相同:
void foo(int *arr, int size);
这意味着数组的行为不像值类型。尝试“按值”传递数组不会导致将数组的可修改副本传递给函数;相反,该函数有效地“通过引用”接收数组。
第二个后果是数组参数不需要具有完整的数组类型,即可以省略数组大小,因为调整了数组类型并且无论如何都不会使用大小。这意味着,如果您天真地将未指定大小的“数组参数”转换为对数组的引用,则除了添加&
. float (&arr)[10]
.
在我看来,使用原始数组作为参数是非常不可取的。首先是因为它丢弃了类型信息:
void foo(int arr[10]) { // same as void foo(int *arr)
int x = arr[9];
}
int bar[3];
foo(bar); // no compile error! the special array rules discarded the size of the array
并且由于原始数组与其他内置类型不一致,所有这些都具有值语义。由于这些原因,应避免使用原始数组。相反,您可以使用std::array
which 避免内置数组的所有“特殊”规则,因此其行为与内置数组一样。
void foo(std::array<int, 10> arr); // Takes arr by value, modifications will not be visible externally
std::array<int, 3> bar;
foo(bar); // compile error
如果您需要一个动态大小的数组,那么您可以使用它std::vector
。