表按值传递

Table pass by value

本文关键字:按值传递      更新时间:2023-10-16

是否可以按值将原始表传递给函数?我相信这是不可能的,但我正在寻找官方消息来源来证实这一点。


我知道如何通过引用传递表:

template<typename T, size_t N, size_t M>
void first_example(T (&table_in_function)[N][M]) {
//...
}
//...
int a[50][20];
//...
first_example(a);

或者通过std::array,但正如我所悲伤的,我正在寻找原始表的解决方案。简单的想法,删除&,显然是错误的。此外,我也不寻找类似的东西:

template<typename T, size_t N, size_t M>
void third_example(T (&temp_ref)[N][M]) {
T local_table[N][M];
//...
}

我接受像魔术代码和元编程这样的解决方案。

不可能声明数组类型的函数参数。特别是C++标准(§8.3.5/5)规定:

在确定每个参数的类型后,任何类型为"T的数组"或"返回T的函数"的参数分别调整为"指针到T"或"指针到返回T的功能"。

因此,如果您试图创建一个采用数组类型的参数的函数,则编译器会将该参数"调整"为指针。

同样,当/如果您试图将数组传递给函数时,实际传递的是该数组的第一个元素的地址。

处理此的规范方法是使用std::array(或等效的包装类型)。

除此之外,你运气不好,因为C++禁止数组的直接复制初始化:

[C++11: 8.5/16]:[..]初始化程序的语义如下。目标类型是正在初始化的对象或引用的类型,源类型

  • 如果初始值设定项是一个(未加括号)支撑的初始列表,则对象或引用被列表初始化(8.5.4)
  • 如果目标类型是引用类型,请参见8.5.3
  • 如果目标类型是字符数组、char16_t数组、char32_t数组或wchar_t数组,并且初始值设定项是字符串文字,请参见8.5.2
  • 如果初始值设定项是(),则对象被值初始化
  • 否则,如果目标类型是数组,则程序格式不正确[..]

您可以将数组直接传递到函数中的唯一原因是,正如您所知,因为它们的名称实际上会衰减为指针(导致我所称的按句柄传递)。尽管出现在相应的用法语法中,但这在功能上与传递引用没有任何不同。

上面的引用意味着,任何解决数组名称衰减的方法都只会遇到更根本的问题,即数组可能无法直接复制。

这是不可能的。当传递到函数中时,C样式数组会自动衰减为指针。

您必须显式地复制数组。