为什么数组会衰减到模板函数中的指针

Dav*_*rle 7 c++ arrays templates sizeof

我不明白为什么数组衰减到模板函数中的指针.

如果您查看以下代码:当参数被强制为参考(函数f1)时,它不会衰减.在另一个函数中,它衰减了.为什么函数f中的T类型不是const char(buff&)[3]而是const char*(如果我理解正确的话)?

#include <iostream>

template <class T>
void f(T buff) {
    std::cout << "f:buff size:" << sizeof(buff) << std::endl;       //prints 4
}

template <class T>
void f1(T& buff) {
    std::cout << "f:buff size:" << sizeof(buff) << std::endl;       //prints 3
}

int main(int argc, char *argv[]) {
    const char buff[3] = {0,0,0};
    std::cout << "buff size:" << sizeof(buff) << std::endl;         //prints 3
    f(buff);
    f1(buff);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Naw*_*waz 10

这是因为数组不能通过传递给函数.因此,为了使其工作,数组衰减成一个指针,然后通过值传递给函数.

换句话说,按值传递数组类似于使用另一个数组初始化数组,但在C++中,无法使用另一个数组初始化数组:

char buff[3] = {0,0,0};
char x[3] = buff; //error 
Run Code Online (Sandbox Code Playgroud)

因此,如果数组出现在右侧=,则左侧必须是pointer或者reference键入:

char *y = buff; //ok - pointer
char (&z)[3] = buff; //ok - reference
Run Code Online (Sandbox Code Playgroud)

演示:http://www.ideone.com/BlfSv

正是出于同样的原因,auto在下面的每种情况下都有不同的推断(注意autoC++ 11附带):

auto a = buff; //a is a pointer - a is same as y (above)
std::cout << sizeof(a) << std::endl; //sizeof(a) == sizeof(char*)

auto & b = buff; //b is a reference to the array - b is same as z (above)
std::cout << sizeof(b) << std::endl; //sizeof(b) == sizeof(char[3])
Run Code Online (Sandbox Code Playgroud)

输出:

4 //size of the pointer
3 //size of the array of 3 chars
Run Code Online (Sandbox Code Playgroud)

演示:http://www.ideone.com/aXcF5


Mar*_*ork 9

因为数组不能通过值作为函数参数传递.
当你按值传递它们时,它们会衰减成指针.

在这个功能:

template <class T>
void f(T buff) {
Run Code Online (Sandbox Code Playgroud)

T不能char (&buff)[3]因为这是一个参考.编译器会试图char (buff)[3]通过值传递,但这是不允许的.因此,为了使它工作,数组衰减到指针.

你的第二个函数有效,因为这里的数组是通过引用传递的:

template <class T>
void f1(T& buff) {

// Here T& => char (&buff)[3]
Run Code Online (Sandbox Code Playgroud)

  • @MooingDuck:当然这是使`std :: array <>`立即优于原始C-arrays的原因之一. (2认同)