表按值传递

时间:2015-04-28 23:31:28

标签: c++ c++14

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

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

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];
  //...
 }

我接受魔术代码和元编程等解决方案。

3 个答案:

答案 0 :(得分:2)

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

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

  

[C++11: 8.5/16]: [..] 初始值设定项的语义如下。 目标类型是要初始化的对象或引用的类型,源类型是初始化表达式的类型。如果初始化程序不是单个(可能带括号的)表达式,则不定义源类型。

     
      
  • 如果初始化程序是(非括号内的) braced-init-list ,则对象或引用是列表初始化的(8.5.4)。
  •   
  • 如果目标类型是引用类型,请参阅8.5.3。
  •   
  • 如果目标类型是一个字符数组,一个char16_t数组,一个char32_t数组或一个wchar_t数组,并且初始化程序是一个字符串文字,请参阅8.5.2。
  •   
  • 如果初始值设定项为(),则对象将进行值初始化。
  •   
  • 否则,如果目标类型是数组,则程序格式不正确。    [..]
  •   

如你所知,你可以将数组直接传递给函数的唯一原因是因为它们的名字实际上已经衰减为指针(导致我称之为pass-by-handle)。尽管出现了相应的使用语法,但就功能而言,这与传递引用没有任何不同。

上面的引用意味着你可以做的任何事情来解决数组名称衰减只会让你遇到更基本的问题,即数组可能无法直接复制。

答案 1 :(得分:2)

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

  

在确定每个参数的类型后,任何类型为“T of T”或“函数返回T”的参数都将被调整为“指向T的指针”或“指向函数返回T的指针”。

因此,如果您尝试创建一个带有数组类型参数的函数,编译器将“调整”该参数以成为指针。

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

答案 2 :(得分:1)

这是不可能的。传入函数时,C风格的数组会自动衰减为指针。

您必须明确复制数组。