0

I have defined template class in .h file, it includes defining a constructor having ostream class. I don't knot how use the constructor in main.

originally, I want to have summation of the ASCII codes of the stream from input, I need to to it with template class, instead of writing it for each type of variables.

.h file

#ifndef SPYOUTPUT_H
#define SPYOUTPUT_H
#include <iostream>
using namespace std;
template <class T>
class SpyOutput {
    int Count, CheckSum;
    ostream* spy;
public:
    int getCheckSum();
    int getCount();

    ~SpyOutput();
    SpyOutput(ostream* a);
    SpyOutput & operator << (T  val);
}
#endif

.cpp

template <class T>
SpyOutput<T>::SpyOutput(std::ostream* a) {
    spy = a;
    Count = 0;
    CheckSum = 0;
}

template <class T> SpyOutput<T>::~SpyOutput() {}

template <class T> SpyOutput<> & SpyOutput<T>::operator << (T  val) {
    stringstream ss;
    ss << val;
    string s;
    s = ss.str();
    *spy << s;
    Count += s.size();
    for (unsigned int i = 0; i < s.size(); i++) {
        CheckSum += s[i];
    }
    return *this;
}

template <class T>
int SpyOutput<T>::getCheckSum() {
    return CheckSum;
}

template <class T>
int SpyOutput<T>::getCount() {
    return Count;
}

main.cpp

#include "SpyOutput.h"
#include <iostream>
#define endl   '\n'

int main()
{
    double d1 = 12.3;
    int i1 = 45;
    SpyOutput spy(&cout); // error agrument list of class template is missing
    /* 
    template <class T> SpyOutput<T> spy(&cout); // not working error
    SpyOutput<ostream> spy(&cout);
    // not working error  having error on operator <<not matches with these oprands
    */

    spy << "abc" << endl;
    spy << "d1=" << d1 << " i1=" << i1 << 'z' << endl;

    cout << "count=" << spy.getCount() << endl;
    cout << "Check Sum=" << spy.getCheckSum() << endl;
    return 0;
}
François Andrieux
  • 28,148
  • 6
  • 56
  • 87
navhzd
  • 1
  • The type to provide for template instantiation would be the type you're outputting. In this case, `const char*` should work. But you're going to have difficulties with your template being [split between .h and .cpp files](https://stackoverflow.com/q/495021/10077). – Fred Larson Sep 28 '17 at 20:20
  • Also, your use of `using namespace std;` in a header file [is an abomination](https://stackoverflow.com/q/1452721/10077). – Fred Larson Sep 28 '17 at 20:23

1 Answers1

1

You're mixing use of class template with function template. If I understand correctly you want to create wrapper around cout which will have templated operator<< to use with any other type. Right now you declare class which is templated for any other type.

The difference is that right now you would need to create separate wrapper for int and char and float and so on... and use appropriate wrapper instance when printing(which would be tedious at best).

To use it as a drop-in replacement for cout change your class to non-templated class and just make operator<< a template like so:

#ifndef SPYOUTPUT_H
#define SPYOUTPUT_H

#include <iostream>

class SpyOutput {
    int Count, CheckSum;
    std::ostream* spy;
public:
    int getCheckSum();
    int getCount();

    ~SpyOutput();
    SpyOutput(std::ostream* a);
    template <class T>
    SpyOutput & operator << (T  val) {
        //  here copy the implementation from .cpp
        //  so that template is instantiated for 
        //  each type it is used with
    }
}
#endif
bezet
  • 810
  • 7
  • 13