C++ C++;11函数中无大小的数组按引用传递
我想知道是否有任何方法可以避免在函数中提到数组的大小。下面是我的简单代码。每次在main中创建数组时,我都必须更改函数passbyref的引用数组的大小。 非常感谢C++ C++;11函数中无大小的数组按引用传递,c++,arrays,c++11,C++,Arrays,C++11,我想知道是否有任何方法可以避免在函数中提到数组的大小。下面是我的简单代码。每次在main中创建数组时,我都必须更改函数passbyref的引用数组的大小。 非常感谢 #include<iostream> #include<string> #include<iomanip> #include<array> using namespace std; class GradeBook { public: void change
#include<iostream>
#include<string>
#include<iomanip>
#include<array>
using namespace std;
class GradeBook {
public:
void changevalues()
{
cout<<arr2[2]<<endl;
arr2[2]=2;
cout<<arr2[2]<<endl;
}
void passbyref(array<int,5>& refvar) //here 5 I have to mention myself
{
refvar[2]=2;
}
private:
array <int,5> arr2;
};
int main() {
array <int,5> grades1{1,1,1,1,1};
GradeBook obj1;
cout<<"grades[2] before change =" <<grades1[2]<<endl;
obj1.passbyref(grades1);
cout<<"grades[2] after change =" <<grades1[2];
}
#包括
#包括
#包括
#包括
使用名称空间std;
班级成绩册{
公众:
void changevalues()
{
cout可以在passbyref
函数中将数组大小指定为模板参数
template <std::size_t N>
void passbyref(array<int,N>& refvar) {
}
模板
void passbyref(数组和refvar){
}
N
的值将被自动扣除,因此无需在调用者中指定该值。这样,如果您在main
中更改大小,则passbyref
中不需要任何更改。您最好使用动态数组,其长度可以在运行时更改。最简单的方法是动态数组使用的是内部管理数组的
void passbyref(std::vector<int>& refvar) // no need to mention size
{
if(refvar.size() > 2)
refvar[2] = 2;
}
// ...
int main() {
std::vector<int> grades1 {1, 1, 1, 1, 1}; // any length you want
passbyref(grades1);
}
void passbyref(std::vector&refvar)//无需提及大小
{
如果(refvar.size()>2)
refvar[2]=2;
}
// ...
int main(){
std::vector grades1{1,1,1,1,1};//任意长度
passbyref(1年级);
}
std::array
的思想是,大小与类型一样是特定数组的一个组成部分,这使得它比c样式数组更干净,但这意味着在函数中,必须存在预期的大小
可能的解决办法:
- 模板,但是
是正确的容器吗std::array
- typedef(或使用):
typedef std::array MySpecificArray
std::vector
这是C++中的一个常见问题:无法声明大小为常量且仅在运行时已知的顺序容器。这是原因之一(以及C兼容性)一些编译器特别是GCC和CLAN,允许C++中的可变长度数组作为编译器扩展。<代码> <代码>。如果只有几个大小,将是编译时表达式,则可以使用模板整数值来计算大小(<代码> STD::数组< /代码>)在任何其他情况下,你都必须依赖于<代码> STD::向量< /代码>,以C++一致性的方式。模板是你的朋友。下面的函数与任何可以用方括号索引的数组类型一起工作,并有一个可转换为INT.< /P>的值类型。
#include<iostream>
#include<string>
#include<iomanip>
#include<array>
using namespace std;
class GradeBook {
public:
void changevalues()
{
cout<<arr2[2]<<endl;
arr2[2]=2;
cout<<arr2[2]<<endl;
}
template<typename Arr>
void passbyref(Arr& refvar) //here 5 I have to mention myself
{
auto N = distance(begin(refvar), end(refvar));
cout << "size is " << N << '\n';
refvar[2]=2;
}
private:
array <int,5> arr2;
};
int main() {
array <int,5> grades1{1,1,1,1,1};
GradeBook obj1;
cout<<"grades[2] before change =" <<grades1[2]<<endl;
obj1.passbyref(grades1);
cout<<"grades[2] after change =" <<grades1[2];
return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
班级成绩册{
公众:
void changevalues()
{
coutPerhaps您希望切换到使用std::vector。使用模板参数作为长度,或auto
,但请注意,对于所使用的每种大小的数组,这将编译为该函数的单独实例。如果您使用的大小超过两种,则向量可能更合适。甚至无需坚持使用std::array。“扣除。“Har H.VLA没有解决这个问题,它只在语句关闭中工作,并且基本上是一个在动态内存中分配数组的语法糖。”Swift:不,VLA是函数唯一声明一个数组的唯一方法,该数组在运行时只知道大小,是唯一通过多维数组的唯一方法。C++习语(vector或vector)如果真的远离2D(矩形)数组,并使用混合语言编程(例如C++和Fortran)harderI很清楚后一点,我不是指。我的意思是,声明的数组是在堆中创建的(没有其他方法实现)。如果我们将大小N作为变量,那么int a[N]带有VLA的
相当于int*a=new int[N]
和作用域末尾的相应删除。多维数组作为地址传递到该区域的开头,编译器GRAD暗示索引数学是有用的。