引用数组和数组作为函数参数有什么区别?

Whats the difference between reference to an array and array as a parameters in functions?

引用数组的函数有什么区别:

// reference to array
void f_(char (&t)[5]) {
    auto t2 = t;
}

简单数组:

// just array
void f__(char t[5]) {
    auto t2 = t;
}

作为参数?

调用代码为:

char cArray[] = "TEST";
f_(cArray);
f__(cArray);

char (&rcArr)[5] = cArray;
f_(rcArr);
f__(rcArr);

在这两种情况下,t2 都是 char*,但在第一个函数中,我的 VS2019 显示 t 内部函数的类型为 char(&t)[]t 内部第二个函数的类型为 char*.

那么说到底,这些函数之间有什么实际区别吗?

您可以指定一个完整的数组类型参数,例如

void f( int ( &a )[N] );

并且在函数中您将知道传递的数组中的元素数。

当函数被声明为

void f( int a[] );

然后编译器将函数声明调整为

void f( int *a );

并且您无法确定传递的数组中的元素数量。所以你需要指定第二个参数,比如

void f( int *a, size_t n );

还可以重载具有引用数组参数类型的函数。例如这两个声明

void f( int ( &a )[] );

void f( int ( &a )[2] );

声明两个不同的函数。

并且可以使用花括号列表调用具有引用数组参数类型的函数(前提是相应的参数具有限定符 const),例如

f( { 1, 2, 3 } );

这是一个演示程序

#include <iostream>

void f( const int ( &a )[] )
{
    std::cout << "void f( const int ( & )[] ) called.\n";
}

void f( const int ( &a )[2] )
{
    std::cout << "void f( const int ( & )[2] ) called.\n";
}

void f( const int a[] )
{
    std::cout << "void f( const int [] ) called.\n";
}


int main()
{
    f( { 1, 2, 3 } );
}

程序输出为

void f( const int ( & )[] ) called.

由于不能按值传递数组(C++ 继承的 C 限制),任何将参数声明为数组的参数都会 'decay' 变成指针(失去其大小)。所以声明

void f__(char t[5])

等同于

void f__(char *t)

其他所有内容都由此而来——在 f__ 的主体内,t 具有指针类型,而不是数组类型。因此,从中推断出的任何 auto 都将基于该指针类型。