• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 345
  • Last Modified:

Template Function to reciveve an array of elements

I need to know how to write a template function that will recieve an array of elements of type K, of any size, add up the elements using the + operator, and return the sum to the calling function (only has to handle arrays).  This function should be usable for any data type K for which the operator + is defined.
0
waylonwhales
Asked:
waylonwhales
  • 7
  • 5
1 Solution
 
CayceCommented:
This really looks like homework to me.

Basically you can create a template to a vector of any type the perform the sum of each member.

Your declaration would be something like this:

template<class T>
void Sum(T& result, std::vector<T> array);

you could also use:

templace<class T>
T Sum(std::vector<T> array);

In the first case the caller is reponsible for sending a T value of 0 (whatever zero is for T type), on the second case, you MUST assign the result to the first element of the array, then add the rest of them.

Now just implement the sum using an iterator. If the type T doesn't support the + operator the compiler will issue an error.
0
 
waylonwhalesAuthor Commented:
yes this is a project
the purpose of Writing this template function is to use it to simplify an application program to read a sequence of values of a specific type into an appropriate array(which comes from a simple text file), call the template function to obtain the sum, and print the result.

template<class T>
T Sum (TList[ ], ....)
{
     for (i = 0, i < TList[ ], i++) //traverse through the array
       if (list != null)
       {
            //add up the elements and return a sum??  list[?] = a+b+c+.....
       }
       else
       {
         cout << "....... ...." << endl;
      }

int main ()
{
  a_file.open("words.txt");
 .
 .
 .
}
questions...
the array is of unknown size...but is limited, and of unknown type...but the
template function handles the type differences
how do you code an addition of an unknown amount of elements
do you use the traversal...
int j = Tlist[i].size()
cout <<  j << endl;  ??
I just need some insight to fill in my missing code to get this thing to work
thanks again for your time
0
 
CayceCommented:
You'll be better using the STL vector instead of your own list. Those have a size() property.

The thing is, that the procedure you're asking for results so simple that giving you more help would be doing it for you :)

#include <vector>

template<class T>
T Sum(std::vector<T>& array)
{
  T result;
  if(array.size() > 0)
  {
    result = array[0];
    for(unsigned int i = 1; i < array.size(); i++)
      result = result + array[i];
  }
  return result;
}

Note, that the above code will require the next thing from the T type:

1) T must support the + operator

2) T must have a default constructor, if it doesn't you should make another procedure like this:

T& Sum(T& result, std::vector<T>& array)
{
  if(array.size() > 0)
  {
    result = array[0];
    for(unsigned int i = 1; i < array.size(); i++)
      result = result + array[i];
  }
  return result;
}

Why? Because on the previous version of the procedure there was this line:
T result;
T could be as simple as a char, but it also could be a very complicated class which requires a lot of memory and doesn't have a default constructor (with no parameters).

3) T should have the assignment operator overloaded.

That means a class should be like this to work fine with your Sum()
// a basic example
class C
{
private:
  float val;
public:
 C()
 {
  val = 0;
 }
 C(const C& c)
 {
  *this = c;
 }
 C& operator=(const C& c)
 {
  val = c.val;
  return *this;
 }
 friend C operator + (C& c1, C& c2):
};

C operator + (C& c1, C& c2)
{
  C c3;
  c3.val = c1.val + c2.val;
  return c3;
}
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
waylonwhalesAuthor Commented:
my simple template program is almost complete...except I'm getting a error that i'm not sure how to fix.  Here is the complete code:


using namespace std;

template<class T>
T Sum(std::vector<T>& array, int amount)
{
  T result;
  if(amount > 0)
  {
    result = array[0];
    for(unsigned int i = 1; i < amount; i++)
      result = result + array[i];
  }
  return result;
}

int main()
{
   
      int element_position = 0;
      const int elements_capacity = 100;
      int elements[elements_capacity];
      
      string line1;
      int answer1;
      ifstream a_file;
      a_file.open("template_test.txt");
      if (a_file.fail())
         {
            cout << "Error opening" << "template_test.txt" << "\n";
            return 1;
         }

      //for every int successfully read
        while ( element_position < elements_capacity
                  && (a_file >> elements[element_position]) )
        {
             
             element_position++;
             
        }

     
        answer1 =  Sum (elements, element_position);
      cout << answer1 << endl;
      a_file.close();

//here is the error message....

Compiling...
Tfunction.cpp
c:\program files\microsoft visual studio\myprojects\lab6\tfunction.cpp(64) : error C2784: 'T __cdecl Sum(class std::vector<T,class std::allocator<T> > &,int)' : could not deduce template argument for 'class std::vector<_Ty,class std::allocator<_Ty>
> &' from 'int [100]'
Error executing cl.exe.

Tfunction.obj - 1 error(s), 0 warning(s)

//if I could get this error fixed...I think the program will work!  Thanks for the
expertise!!
0
 
CayceCommented:
You need to specifiy the type on the call to sum:

Like this

 answer1 =  Sum<int>(elements, element_position);
0
 
CayceCommented:
BTW: you are not really using STL vectors, so change Sum declaration to:

template<class T>
T Sum(T array[], int amount)
0
 
waylonwhalesAuthor Commented:
yes the first part of the project works...! thank you!
but I still have one more question.....
the code calls the (integers) from a line of text in a file called variable a_file
this file has two more lines of text of different type. It looks like this:

37 -500 99 1024 365 5 8 101 -77 280 311 260 445
1.2 2.345 3.57999 -273.48967 0.0 55.66 -3.545
Alph beti zing Is No Job For A Hig hl y Pa id Prog ramm er!

The program makes use of the template and adds up the integers from line 1 nicely.
I want the program to go to the next line and use the template to add them as well.
Now since these two lines are of different type, I must specify a new array of type double correct?  As well as rename my variables to accept type double...I also closed the file and reopened it...(b_file) which I didn't want to do.  How do I get the program to look to line 2 for the type double? I thought it would be as simple as adding a very similar block of code.  (And finally line 3 for type string)? Here is the code with errors:

using namespace std;

template<class T>
T Sum(T array[], int amount)

{
  T result;
  if(amount > 0)
  {
    result = array[0];
    for(unsigned int i = 1; i < amount; i++)
      result = result + array[i];
  }
  return result;
}

int main()
{
   
      int element_position = 0;
      const int elements_capacity = 100;
      int elements[elements_capacity];
      
      
      int answer1;
      ifstream a_file;
      
      a_file.open("template_test.txt");
      
      if (a_file.fail())
         {
            cout << "Error opening" << " template_test.txt" << "\n";
            return 1;
         }

      //for every int successfully read
        while ( element_position < elements_capacity
                  && (a_file >> elements[element_position]) )
        {
             
             element_position++;
             
        }

     
        answer1 =  Sum(elements, element_position);
      cout << answer1 << endl;
      a_file.close();
   //*******************************************************

      
      double new_element_position = 0;
      const double new_elements_capacity = 100;
      double new_elements[elements_capacity];

      double answer2;

      ifstream b_file;
      
      b_file.open("template_test.txt");
      
      if (b_file.fail())
         {
            cout << "Error opening" << " template_test.txt" << "\n";
            return 1;
         }
      
      
      //for every double successfully read
        while ( new_element_position < new_elements_capacity
                  && (b_file >> new_elements[new_element_position]) )
        {
             
             new_element_position++;
             
        }

     
        answer2 =  Sum(new_elements, new_element_position);
      cout << answer2 << endl;

         b_file.close();

        
}

Tfunction.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\Lab6\Tfunction.cpp(92) : error C2108: subscript is not of integral type
C:\Program Files\Microsoft Visual Studio\MyProjects\Lab6\Tfunction.cpp(92) : error C2679: binary '>>' : no operator defined which takes a right-hand operand of type 'double *' (or there is no acceptable conversion)
C:\Program Files\Microsoft Visual Studio\MyProjects\Lab6\Tfunction.cpp(92) : fatal error C1903: unable to recover from previous error(s); stopping compilation
Error executing cl.exe.

Tfunction.obj - 3 error(s), 0 warning(s)  

0
 
CayceCommented:
looks like you should be reading line by line, then using a text stream to parse the lines into ints, then doubles, then strings.

Your loop where you read from the file is incorrect.

Another recommendation would be to use vector instead of arrays.
0
 
waylonwhalesAuthor Commented:
A vector would be much better...because it is more dynamic...but unfortunately I cannot use a vector (according to the rules).  I can't seem to find an example of how to continue the reading of my text file to incorporate the next line of text.  What I do know is that once the >> extraction reaches the newline ch. at the end of the first line of text it reaches a fail state and terminates the read.  The type difference here in the text file is really causing problems especially with the limited use of the array.  I would like to know if there is a way to create a loop with a counter and a test to handle the different types in one shot?
0
 
CayceCommented:
Use a strstream for each line. Something like this:

#include <strstream>
#include <fstream>
foo()
{
  fstream f;
  f.open("myfile.txt");
  char buffer[1024] = {0};

  f.getline(buffer, 1024);
  strstream ss_int(buffer, 1024);
  //
  // Read ints from ss_int;
  //
  f.getline(buffer, 1024);
  strstream ss_double(buffer, 1024);
  //
  //  Read doubles from ss_double
  //
  f.close();
}
0
 
waylonwhalesAuthor Commented:
wow, that worked...I have three different outputs for the three different types...although I'm sure that it isn't entirely correct output.  The syntax produces no errors but the logic still isn't right.  (And I still can't rename my variable to reflect the type I'm dealing with...it always wants ints)  I"ll show the complete coding below with output:

using namespace std;

template<class T>
T Sum(T array[], int amount)

{
  T result;
  if(amount > 0)
  {
    result = array[0];
    for(unsigned int i = 1; i < amount; i++)
      result = result + array[i];
  }
  return result;
}

int main()
{
   
      int element_position = 0;
      const int elements_capacity = 100;
      int elements[elements_capacity];
      int new_element_position = 0;
      const int new_elements_capacity = 100;
      int new_elements[new_elements_capacity];
      int new2_element_position = 0;
      const int new2_elements_capacity = 100;
      int new2_elements[new2_elements_capacity];
      
      int answer1;
      double answer2;
      string answer3;
      fstream a_file;
      char buffer[1024] = {0};
      
      a_file.open("template_test.txt");
      
      if (a_file.fail())
         {
            cout << "Error opening" << " template_test.txt" << "\n";
            return 1;
         }

     a_file.getline(buffer, 1024);
     strstream ss_int(buffer, 1024);
  //
  // Read ints from ss_int;
  //
 
      
        while ( element_position < elements_capacity
                  && (ss_int >> elements[element_position]) )
        {
             
             element_position++;
             
        }

     
        answer1 =  Sum(elements, element_position);
      cout << answer1 << endl;
     
   //*******************************************************
 
        
        
        a_file.getline(buffer, 1024);
        strstream ss_double(buffer, 1024);
      //
      //  Read doubles from ss_double
      //
 
 
  while ( new_element_position < new_elements_capacity
                  && (ss_int >> new_elements[new_element_position]) )
        {
             
             new_element_position++;
             
        }

      answer2 =  Sum(new_elements, new_element_position);
      cout << "\n" << answer2 << endl;


 //**********************************************************


        a_file.getline(buffer, 1024);
        strstream ss_string(buffer, 1024);
      //
      //  Read string from ss_string
      //
 
 
  while ( new2_element_position < new2_elements_capacity
                  && (ss_int >> new2_elements[new2_element_position]) )
        {
             
             new2_element_position++;
             
        }

      answer3 =  Sum(new2_elements, new2_element_position);
      cout << "\n" << answer3 << endl;
 
        
        a_file.close();       
}

output:
2358
-8.58993e +008
|}

 text file:
37 -500 99 1024 365 5 8 101 -77 280 311 260 445
1.2 2.345 3.57999 -273.48967 0.0 55.66 -3.545
Alph beti zing Is No Job For A Hig hl y Pa id Prog ramm er!
 
0
 
CayceCommented:
Shouldn't your arrays be:

     int int_element_position = 0;
     const int int_elements_capacity = 100;
     int int_elements[elements_capacity];
     int double_element_position = 0;
     const int double_elements_capacity = 100;
     double double_elements[double_elements_capacity];
     int string_element_position = 0;
     const int string_elements_capacity = 100;
     string string_elements[string_elements_capacity];

And call Sum like this:

  int int_answer = Sum<int>(int_elements, int_element_position);
// ...
  double double_answer = Sum<double>(double_elements, double_element_position);
// ...
  string string_answer = Sum<string>(string_elements, string_element_position);

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 7
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now