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

hgr*_*rev 7 c++ pass-by-reference implicit-conversion c++11

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

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

和简单的数组:

// just array
void f__(char t[5]) {
    auto t2 = t;
}
Run Code Online (Sandbox Code Playgroud)

作为参数?

调用代码为:

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

char (&rcArr)[5] = cArray;
f_(rcArr);
f__(rcArr);
Run Code Online (Sandbox Code Playgroud)

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

那么到底这些功能之间有什么实际区别吗?

Vla*_*cow 2

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

void f( int ( &a )[N] );
Run Code Online (Sandbox Code Playgroud)

在函数中,您将知道传递的数组中的元素数量。

当函数声明如下时

void f( int a[] );
Run Code Online (Sandbox Code Playgroud)

然后编译器调整函数声明,例如

void f( int *a );
Run Code Online (Sandbox Code Playgroud)

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

void f( int *a, size_t n );
Run Code Online (Sandbox Code Playgroud)

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

void f( int ( &a )[] );
Run Code Online (Sandbox Code Playgroud)

void f( int ( &a )[2] );
Run Code Online (Sandbox Code Playgroud)

声明两个不同的函数。

具有引用数组参数类型的函数可以使用大括号列表来调用(假设相应的参数具有限定符 const),例如

f( { 1, 2, 3 } );
Run Code Online (Sandbox Code Playgroud)

这是一个演示程序

#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 } );
}
Run Code Online (Sandbox Code Playgroud)

程序输出是

void f( const int ( & )[] ) called.
Run Code Online (Sandbox Code Playgroud)