C ++ 11数组按引用传递,函数中没有大小

Posted

技术标签:

【中文标题】C ++ 11数组按引用传递,函数中没有大小【英文标题】:C++ 11 array pass by reference without size in function 【发布时间】:2018-03-19 06:50:16 【问题描述】:

我想知道有什么方法可以避免在函数中提及数组的大小。下面是我的简单代码。每次我在 main 中创建一个数组时,我都必须更改函数 passbyref 的引用数组的大小。 非常感谢。

#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> grades11,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::vector。 使用模板参数作为长度,或者auto 【参考方案1】:

数组大小可以在passbyref函数中指定为模板参数。

template <std::size_t N>
void passbyref(array<int,N>& refvar) 


N的值会被自动扣除,调用者中无需指定。这样,如果您更改main 的大小,passbyref 将不需要任何更改。

【讨论】:

虽然请注意,对于您使用的每个大小的数组,这将编译成此函数的单独实例。如果您使用的尺寸超过几个尺寸,则矢量可能更合适。 甚至不需要坚持std::array。 “扣除。”哈哈。【参考方案2】:

模板是你的朋友。下面的函数适用于任何可以用方括号索引并具有可转换为 int 的值类型的数组类型。

#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> grades11,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;

【讨论】:

很高兴为您服务。【参考方案3】:

您最好使用动态数组 - 它的长度可以在运行时改变。使用动态数组最简单的方法是使用在内部管理数组的std::vector。

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);

【讨论】:

【参考方案4】:

std::array 的想法是大小是特定数组的一个组成部分,就像类型一样,这使得它比 c 风格的数组更干净,但这意味着在函数中,必须存在预期的大小.

可能的解决方案:

模板,但是std::array 是正确的容器吗? typedef(或使用):typedef std::array&lt;int,5&gt; MySpecificArray std::vector

【讨论】:

【参考方案5】:

&lt;rant: on&gt;这是 C++ 中的一个常见问题:无法声明一个大小恒定且仅在运行时知道的顺序容器。这是原因之一(以及 C 兼容性),而一些编译器,尤其是 gcc 和 clang,允许 C++ 中的可变长度数组作为编译器扩展。&lt;rant: off&gt;。如果只使用几个大小并且将是编译时表达式,则可以使用模板整数值作为大小 (std::array&lt;int, sz&gt;)。在任何其他情况下,您将不得不依赖 std::vector 来获得符合 C++ 的方式。

【讨论】:

vla 并没有解决这个问题,它只在语句闭包中起作用,本质上是在动态内存中分配数组的语法糖。 @Swift:没有。 VLA 是函数正确声明其大小仅在运行时知道的数组的唯一方法,并且是干净地传递多维数组的唯一方法。 C++ 习语(向量或向量)如果离二维(矩形)数组真的很远,会使混合语言编程(例如 C++ 和 Fortran)更难 我知道后面一点,我不是故意的。我的意思是,声明的数组是在堆中创建的(没有其他方法可以实现)。如果我们将大小 N 作为变量,则带有 VLA 的 int a[N]; 等效于 int *a = new int[N] 并在范围末尾分别删除。多维数组作为地址传递到此类区域的开头,编译器隐含索引数学

以上是关于C ++ 11数组按引用传递,函数中没有大小的主要内容,如果未能解决你的问题,请参考以下文章

C语言中的值传参和引用传参是指啥?

在c语言编程中,传值方式和传引用方式之间有啥区别?

值传递和引用传递的区别

JAVA中的值传递和引用传递问题

C++ 把引用作为函数参数

参数传递(值传递与引用传递)