在以下代码中,std::extent<decltype(columns)>::value
计算给定数组的长度。但是,当数组是函数参数时,编译器的行为方式不同。有人可以帮我解决这个问题吗?
输出:
本地数组长度:5
函数数组长度:0
代码:
#include <iostream>
#include <string>
void showcolumns_num(std::string columns[])
{
int columns_num=std::extent<decltype(columns)>::value;
std::cout<<"function array length: "<<columns_num<<std::endl;
}
int main()
{
std::string column_list[]={"col1","col2","col3","col4","col5"};
// local calculation of column number
int columns_num=std::extent<decltype(column_list)>::value;
std::cout<<"local array length: "<<columns_num<<std::endl;
// function calculation of column number
showcolumns_num(column_list);
return 0;
}
答案 0 :(得分:4)
你必须通过引用传递数组,以避免衰减到指针,这会失去大小信息:
template <std::size_t N>
void showcolumns_num(std::string (&columns)[N])
答案 1 :(得分:2)
简短的回答是:不要使用数组。而不是string columns[N];
,请使用vector<string> columns;
或vector<string> columns(N,"");
。在这个答案中,我将更多地谈论数组,它们是有趣的&#34;。但数组很有趣&#34;在癌症有趣的方式,有人必须了解癌症,但我们想摆脱它,大多数人不想成为专家。
C数组真的很奇怪。它们不能通过值传递,但它们可以通过引用传递,而C ++使它变得非常容易。如果你确定 - 作为一项智力练习 - 传递数组,那么你可以使用它:
template<size_t N>
void showcolumns_num(std::string (&columns)[N])
非数组类型(如int
或struct Person
或list<vector<string>>
)可以通过引用传递值或。但数组不能通过值传递。
如果您尝试按值传递数组,编译器将执行一个技巧,而不是将指针传递给数组的第一个元素。这称为指针衰减。
这意味着,在没有警告的情况下,编译器将重写您的函数声明
void showcolumns_num(std::string columns[]) { // this is what you write
// changed to
void showcolumns_num(std::string* columns) { // ... but this is what you get
,对showcolumns_num
的每次调用都将改为:
showcolumns_num(column_list); // this is what you write
// changed to
showcolumns_num(&(column_list[0])); // ... but this is what you get
这背后的原因是历史性的,并且与早期的B语言有关。
变量被声明为局部变量,或全局变量或函数参数。对于局部变量和全局变量,编译器通常会尊重您的意愿,但不会考虑函数参数:
void foo(int x[5]) { // silently converted to int *x
int y[10]; // y really will be an array
}
答案 2 :(得分:2)
因为声明:
void showcolumns_num(std::string columns[])
与:
相同void showcolumns_num(std::string * columns)
但声明:
std::string column_list[]={"col1","col2","col3","col4","col5"};
与:
相同std::string column_list[5]={"col1","col2","col3","col4","col5"};
所以编译器不知道函数内部的数组大小。
只需使用std::vector< std::string >
。