简体   繁体   English

将在 C++ 中添加任何二维整数数组的所有元素的函数模板

[英]Function Template that will add all elements of any 2-D integer array in C++

I have been tasked with creating a function template that will add all elements of any 2-dimensional integer array as part of an exercise for a programming theory language course.我的任务是创建一个函数模板,该模板将添加任何二维整数数组的所有元素,作为编程理论语言课程练习的一部分。

I have tried several methods and keep getting compiler errors that I don't understand.我尝试了几种方法,但不断收到我不明白的编译器错误。

1) 1)

template<typename T>
T addArraysOne(T rows, T cols, T arr[][cols])
{
    T output;
    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
            output += arr[i][j];
        }
    }
    return output;
}

This one errors as the parameter for the number of columns is "not a constant".这个错误是因为列数的参数是“不是常数”。

2) 2)

int addArraysTwo(int rows, int cols, int** arr)
{
    int output;
    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
            output += *arr[i*rows+j];
        }
    }
    return output;
}

This one errors when I try and call it with addArraysTwo(5, 5, arr);当我尝试使用addArraysTwo(5, 5, arr);调用它时出现此错误addArraysTwo(5, 5, arr); because it "does not match the function call", when "arr" is a 2 dimensional int array.因为它“与函数调用不匹配”,当“arr”是一个二维 int 数组时。 I haven't found any problems particularly similar to this online.我在网上没有发现任何与此特别相似的问题。 Any suggestions on how to modify these so that I do not piss off the compiler would be much appreciated.任何关于如何修改这些以便我不惹恼编译器的建议将不胜感激。 Thanks!谢谢!

You can use the following program that uses template nontype parameters .您可以使用以下使用模板非类型参数的程序

Version 1 : For integer arrays版本 1 :对于整数数组


#include <iostream>
//a function template that takes a 2D int array by reference
template< std::size_t N, std::size_t M>
int calculateSum(int (&arr)[N][M])
{
    int sum = 0;
    //iterate through rows and colums of the passed 2D int array
    for(std::size_t row = 0; row < N; ++row)
    {
        for(std::size_t col = 0 ; col < M; ++col)
        {
            sum+= arr[row][col];
        }
    }
    return sum;
}
int main()
{
    int arr[2][3] = {{1,2,3},{3,4,5}};
    std::cout<<"Sum is: "<<calculateSum(arr)<<std::endl;

    return 0;
}

Version 2 : For array of arbitrary type版本 2 :用于任意类型的数组


#include <iostream>
//a function template that takes a 2D array(with elements of type T) by reference
template< typename T, std::size_t N, std::size_t M>
T calculateSum(T (&arr)[N][M])
{
    T sum{0};
    //iterate through rows and colums of the passed 2D T array
    for(std::size_t row = 0; row < N; ++row)
    {
        for(std::size_t col = 0 ; col < M; ++col)
        {
            sum+= arr[row][col];
        }
    }
    return sum;
}
int main()
{
    double arr[2][3] = {{1.4,2,3},{3.6,4,5.45}};
    std::cout<<"Sum is: "<<calculateSum(arr)<<std::endl;

    return 0;
}

Your first method, variable-lengthed-array only supported by c99 (and not adopted by c++ I believe?).您的第一种方法,可变长度数组仅受 c99 支持(我相信 c++ 未采用?)。 otherwise, the length of the array must be known at compile time.否则,必须在编译时知道数组的长度。 And at least with c++17 and below, any parameter of array type is adjusted to the corresponding pointer type by the compiler, so it is no difference between int f(int a[5]) and int f(int a[]) and int f(int* a) 。But for 2d arrays, the size of the second dimension must be known at compile time.而且至少在c++17及以下,任何数组类型的参数都会被编译器调整为对应的指针类型,所以int f(int a[5])int f(int a[]) int f(int a[5])没有区别int f(int a[])int f(int* a) 。但是对于二维数组,在编译时必须知道第二维的大小。 int f(int a[][2]) (which is equavalent to int f(int(*a)[2]) ) is OK, but int f(int a[][]) is not. int f(int a[][2]) (相当于int f(int(*a)[2]) )是可以的,但int f(int a[][])不是。

Your second method, 2d arrays are not implicitly convertable to pointer of pointers, but pointer to 1d arrays:您的第二种方法,二维数组不能隐式转换为指针指针,而是指向一维数组的指针:

int arr[2][3];
int **p = arr; // Error
int(*p)[3] = arr; // OK

so one of the solutions is just:所以解决方案之一就是:

template<typename T>
T addArraysOne(T rows, T cols, T* arr)
{
    T output = 0; // NOTE: initialize to 0
    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
            output += arr[i*cols+j]; // NOTE: not i*rows+j
        }
    }
    return output;
}

and called it with:并用以下命令调用它:

int arr[2][3];
addArraysOne(2, 3, &arr[0][0]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM