0

So I created a Person class that now i'm trying to convert into a template class but I keep getting the following errors:

  error: template-id ‘operator<< <std::vector<int, std::allocator<int> > >’ for ‘std::ostream& operator<<(std::ostream&, Person<std::vector<int, std::allocator<int> > >&)’ does not match any template declaration
      friend std::ostream& operator<<<T>(std::ostream&, Person<T>& m);

error: template-id ‘operator>><std::vector<int, std::allocator<int> > >’ for ‘std::istream& operator>>(std::istream&, Person<std::vector<int, std::allocator<int> > >&)’ does not match any template declaration
  friend std::istream& operator>><T>(std::istream&, Person<T>& lass);

I had a look at similar issues people faced and posted here but I couldn't find a solution that would work for me so I decided to ask my own question. Would mean a lot if you guys can help! I'm very new to C++ and its sort of confusing..

here is my code for header and cc header:

#ifndef _Person_H_
#define _Person_H_

#include <iostream>
#include <sstream>
#include <vector>
template<class T>
class Person{
private:
    vector<T> myVector;

public:
    Person(const T vec);
    T getVector();
    ostream& print_on(std::ostream& o);
    friend std::istream& operator>><T>(std::istream&, Person<T>& lass);
    friend std::ostream& operator<<<T>(std::ostream&, Person<T>& m);
};

template<class T> class Person;
template <class T> std::istream& operator>>(std::istream&, Person<T>&);
template <class T> std::ostream& operator<<(std::ostream&, Person<T>&);

#include "Person.cc"
#endif

and here is my cc file

#include <iostream>
#include <vector>
#include <string>

using namespace std;

template <class T>
Person<T>::Person(const T vec) : myVector(vec)
{ }

template <class T>
T Person <T>::getVector() {
    return myVector;
}

template <class T>
ostream& Person<T>::print(ostream& o) {
    return o << "success ";
}

template <class T>
std::ostream& operator<<(std::ostream& o, Person<T>& m) {
    return m.print_on(o);
}

template <class T>
std::istream& operator >> (istream& input, Person<T>& lass)
{
    vector<T> vectors;
    int Vsize,numbers;
    cout<<"Enter size of vector"<<endl;
    input >> Vsize;
            for (int i = 0; i < Vsize; i++)
            {
                input>> numbers;
                vectors.push_back(numbers);
            }

            lass=Person(vectors);
    return input;
}
Joseph Ali
  • 41
  • 4
  • 1
    Anyone who includes this header file will have a ton of bricks fall on their head [courtesy of `using namespace std;`](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). You will do yourself a big favor if you completely forget that this is a part of C++. – Sam Varshavchik Dec 01 '19 at 03:07
  • What is `getVector();`? – Thomas Sablik Dec 01 '19 at 03:27
  • @ThomasSablik just returns the vector – Joseph Ali Dec 01 '19 at 03:28
  • It has no return type in the class declaration. Is there a reason for you use `endl` instead of the better `'\n'`? – Thomas Sablik Dec 01 '19 at 03:28
  • @ThomasSablik it has a return type T.. As for endl.. Idk i just prefer it. Anyway that isn't really causing the main issue here – Joseph Ali Dec 01 '19 at 03:32
  • That's causing the main issue. In the header you have `getVector();`. That's not correct. There are more such errors in your code. In the header you call the function `print`. In the source file the function is called `print_on`. After you fix these errors the answer of @songyuanyao will work – Thomas Sablik Dec 01 '19 at 03:32
  • In `std::istream& operator >> (istream& input, Person& lass)` you are returnin `in` but the stream is called `input`. – Thomas Sablik Dec 01 '19 at 03:35
  • @ThomasSablik oh sorry i didn't realize i didn't put the return type in header class for the code here. that was a typo my bad. either way in my code i have a return type for getVector(); in both classes so the problem is in ostream and istream itself. but thanks for pointing that out i will fix the typo in my question – Joseph Ali Dec 01 '19 at 03:35
  • After you fixed all the "typos" it will work. I fixed about 3 of them and now it compiles and I can use the template. – Thomas Sablik Dec 01 '19 at 03:36
  • @ThomasSablik still showing errors for me.. the class is working for u? im getting same errors idk why :/ can u copy paste what u made? thanks – Joseph Ali Dec 01 '19 at 03:39
  • Did you apply songyuanyao's changes? – Thomas Sablik Dec 01 '19 at 03:39
  • @ThomasSablik Yea and still getting the same issue im losing my mind i dont get why my program is showing this.. – Joseph Ali Dec 01 '19 at 03:42
  • Is it possible that you are editing the wrong file or you are compiling a old version? Here is a working version: https://wandbox.org/permlink/QwcoHNWdsp9LKVC5 – Thomas Sablik Dec 01 '19 at 03:44
  • @ThomasSablik no it also shows the file names.. so i am getting tons of warnings and stuff in different parts of code along with this error. Should I post them in the question as well? maybe one of those warnings is causing this issue? i just figured the main error is causing all the other problems – Joseph Ali Dec 01 '19 at 03:46
  • This question is fixed by the answer. If you still have problems it's probably a different question. I showed you in my link a working code. You should mark the answer because it fixed the problem. – Thomas Sablik Dec 01 '19 at 03:49
  • so in ur code i entered cout<

    – Joseph Ali Dec 01 '19 at 03:50
  • and i removed the argument u passed and replaced it with cin>>p; and cout<

    – Joseph Ali Dec 01 '19 at 03:52
  • Here is the cout: https://wandbox.org/permlink/U9l2oTtH1mPBABiy. You can't remove the argument because there is no default constructor. You have to use the one constructor you provided. But this is completely different issue. This question is about class templates and friend functions. Now you are asking abount default constructors. – Thomas Sablik Dec 01 '19 at 04:00
  • @ThomasSablik hmm alright thanks man. I will have a look and find out whats up with my code. thanks – Joseph Ali Dec 01 '19 at 04:03

1 Answers1

1

You need to move the declaration of operator<< and operator>> before the definition of Person, otherwise the compiler won't know that they're templates in the friend declaration. e.g.

template<class T> class Person;
template <class T> std::istream& operator>>(std::istream&, Person<T>&);
template <class T> std::ostream& operator<<(std::ostream&, Person<T>&);

template<class T>
class Person{
private:
    vector<T> myVector;

public:
    Person(const T vec);
    getVector();
    ostream& print_on(std::ostream& o);
    friend std::istream& operator>><T>(std::istream&, Person<T>& lass);
    friend std::ostream& operator<<<T>(std::ostream&, Person<T>& m);
};

PS: It'll be better to make operator<< taking const Person<T>& and make print a const member function.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405