2

I have a function template and main as follows:

 template <class type > type* calculate(type inputVal) {
       type val;
       static int counter = 0;
       static type sum = inputVal;
       static type average = inputVal;
       static type* address = &sum

       do {
          cout << "Enter value: ";
          cin >> val;
          counter++;
          sum += val;
          average = sum / counter;
       } while (!cin.eof());
      return address;
 }

void main() {
      int num;
      cout << "Enter Value: ";
      cin >> num;
      int *ptr = calculate(num);
      cout << "SUM: " << *ptr << " AVG: " << *(ptr+1);
 }

My problem is that this should work with different input types instead of just int, so if a user first enters a float it'll treat everything as that type, as wells as if the user enters a char.

Also the template function cannot print the end values.

leakybytes
  • 359
  • 4
  • 12
  • 1
    1. Declareing or defining `void main()` in global namespace is illegal in standard C++. You should use `int main()` as entry point. 2. Semicolons are missing after `static type* address = &sum`, `cin >> num` and `calculate(num)` 3. `!cin.eof()` as loop condition [seems bad](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) and I suggest you should check if `cin >> val` is successful instead. – MikeCAT Jul 14 '16 at 05:16
  • `*(ptr+1)` is bad because it dereferences out-of-range. – MikeCAT Jul 14 '16 at 05:20
  • It's not possible. A program cannot decide what type a variable will have based on what it reads from the standard input. All types of all variables must be known in advance. – n. m. could be an AI Jul 14 '16 at 05:45

1 Answers1

1

A normal variable sum is treated as one-element array for pointer aritimetic (N3337 5.7 Additive operators) and when ptr points at it, ptr+1 doesn't point at a valid object and therefore must not be dereferenced. If you want continuous memory region, use arrays.

Also note that

  • Checking !cin.eof() after updating sum and average doesn't seem a good idea because it will use an invalid (duplicate) data. Check if input is successful before processing the data.
  • Declareing void main() (or main with return type other than int) in the global namespace is illegal in the standard C++. Unless you have some special reason -- for example, your boss or teacher forbids writing standard-compliant code -- you should use int main() (in this case).
  • You should initialize counter to 1 to put inputVal in the number. Avoiding getting input as argument to avoid writing duplicate code seems better.

Try this:

#include <iostream>
using std::cin;
using std::cout;

template <class type > type* calculate(type inputVal) {
  type val;
  static int counter = 1;
  static type buffer[2];
  type& sum=buffer[0];
  type& average=buffer[1];
  sum=average=inputVal;
  static type* address = buffer;

  for(;;) {
    cout << "Enter value: ";
    if(!(cin >> val)) break;
    counter++;
    sum += val;
    average = sum / counter;
  }
  return address;
}

int main() {
  int num;
  cout << "Enter Value: ";
  cin >> num;
  int *ptr = calculate(num);
  cout << "SUM: " << *ptr << " AVG: " << *(ptr+1);
}

Or this without input from the argument:

#include <iostream>
using std::cin;
using std::cout;

template <class type > type* calculate() {
  type val;
  static int counter = 0;
  static type buffer[2];
  type& sum=buffer[0];
  type& average=buffer[1];
  sum=0; // the type used has to be capable to be converted from integer 0
  average = 0;
  static type* address = buffer;

  for(;;) {
    cout << "Enter value: ";
    if(!(cin >> val)) break;
    counter++;
    sum += val;
    average = sum / counter;
  }
  return address;
}

int main() {
  int *ptr = calculate<int>();
  cout << "SUM: " << *ptr << " AVG: " << *(ptr+1);
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • is there anyway to do it without the use of arrays? and also what if the user wanted to calculate a float value? – leakybytes Jul 14 '16 at 05:32
  • @GeorgeVentura Use structures to avoid using arrays in this case. Let the user get code to deal with `float` if the user want it. – MikeCAT Jul 14 '16 at 05:34
  • I tried this program is not terminating can you tell when this condition if(!(cin >> val)) will be true – PapaDiHatti Jul 14 '16 at 05:35
  • @GeorgeVentura When the input fails and `cin >> val` returns `false`. – MikeCAT Jul 14 '16 at 05:36
  • Also this program will give wrong output for average because there is one input already in main so counter should be initialized to 1 – PapaDiHatti Jul 14 '16 at 05:38
  • @Kapil In the first code, `counter` is already initialized to 1. In the second code, I don't think there is one input already in main. – MikeCAT Jul 14 '16 at 05:40
  • sorry i just refresh my page. Also one question related to this, Is there any way by which template can deduce its type from left hand side i.e if we call int* ptr = calculate() then it take its type as int – PapaDiHatti Jul 14 '16 at 05:48