3

I was doing some practice questions in C++. I ran into an issue where I want to find the sum of elements of a 2d array. I can write a get sum method which returns the sum. But I was exploring if "operator<<" method could be overloaded to achieve the same result.

#include <iostream>
using namespace std;

int operator<<(const int arr[5][5])
{
   int sum = 0;
   for (int i = 0; i < 5; i++)
   {
      for (int j = 0; j < 5; j++)
      {
         sum += arr[i][j];
      }
   }
   return sum;
}

int main()
{
   int arr[5][5] = { {1,2,3,4,5},
                    {2,3,4,5,6},
                    {3,4,5,6,7},
                    {4,5,6,7,8},
                    {5,6,7,8,9} };
   cout << &arr << endl;
}

I want to achieve the sum as in the std::cout method. Is this possible?

JeJo
  • 26,381
  • 6
  • 42
  • 81
  • 2
    The phrase I use for this that you are "subverting expectations." That's a bad thing. There are two things that `operator< – sweenish Jul 15 '20 at 09:06
  • Of course you can abuse the "ouput operator" to print just the sum. But is this really what you want to achieve here? – churill Jul 15 '20 at 10:54
  • What @sweenish is referring to is the [Principle of least astonishment](https://en.wikipedia.org/wiki/Principle_of_least_astonishment). – DevSolar Jul 15 '20 at 11:01

2 Answers2

4

You can get the desired output by providing a template overload for operator<<, which takes const& int[row][col] as follows. This will work for only int[row][col].

(See Live Online)

#include <iostream>
#include <numeric> // std::accumulate

template<std::size_t M, std::size_t N> 
std::ostream& operator<<(std::ostream& out, const int (&arr)[M][N]) /* noexcept */
{
    int sum = 0;
    for (std::size_t i = 0; i < M; ++i)
    {
#if false // either using `std::accumulate`        
        sum += std::accumulate(arr[i], arr[i] + N, 0);

#elif true // or using for- loop
        for (std::size_t j = 0; j < N; j++)
            sum += arr[i][j];
#endif
    }
    return out << sum;
}

Side Notes:

  • However, you are changing the behavior of 'operator<<' overload. It supposes to print the elements(i.e. array) rather printing the sum of the elements.
  • Also avoid practicing with using namespace std;.
JeJo
  • 26,381
  • 6
  • 42
  • 81
2

using std::accumulate, since the memory in the array is linear, you can use start and end of the array as iterators.

#include <iostream>
#include <numeric>  

int main()
{
    int arr[5][5] = { {1,2,3,4,5},
            {2,3,4,5,6},
            {3,4,5,6,7},
            {4,5,6,7,8},
            {5,6,7,8,9} };
    int sum = 0;
    sum += std::accumulate(arr[0], arr[0]+sizeof(arr)/sizeof(arr[0][0]), 0);
    std::cout << "Sum of array arr[5][5]: " << sum << "\n";


}
nayab
  • 2,342
  • 1
  • 17
  • 34