0

I am trying to overload << for a MemSet template which contains array of objects...but If i am trying to make MemSet of MemSet then overloading do not work

///// SetMain.cpp
int main()
{
     MemSet<Record> mset(10),mset2(10);
     MemSet< MemSet<Record> >mm1(10);
     Record r,r2,r3,r4,r5,r6;


cin>>r;
cin>>r2;
 cin>>r3;
 mset.add(r);
mset.add(r2);
mset.add(r3);
cout<<" Memset 2:"<<endl;

cin>>r4;
cin>>r5;
cin>>r6;
 mset2.add(r);
mset2.add(r2);
mset2.add(r3);


if(mset == mset2)
cout<<"Both memset are equal"<<endl;
else
cout<<"Memsets are not equal"<<endl;

mm1<<mset;
//mset2>>mm2;

if(mm1 == mm2)
cout<<"Both memset of memset are equal"<<endl;
else
cout<<"Memset of memset are not equal"<<endl;


return 0;   
}

Here is the Memset class....

 ////Set and MemSet class

      template <class T>
     class Set
     {
            public :
                virtual bool find(T x) =0;
                virtual bool add(T x)  =0;
    };


template<class T>
class MemSet    : public Set<T> 
{
    public:
    T *array;
    int arraysize,currentsize;
template <class T1> 
friend  istream& operator >> (istream& s,MemSet<T1>& m );
template <class T1> 
friend ostream& operator << (ostream& s,MemSet<T1>& m );        

};


template <class T>
ostream& operator << (ostream& s,MemSet<T>& m )
{
    for(int i=0;i<m.getCurrentsize();i++)
    s << m.array[i];


    return s;
    }

Record class

////Record class
class Record
        {
            public:
            int age;
            std::string first_name,last_name;


friend  istream& operator >> (istream& s,Record& r );
friend ostream& operator << (ostream& s,Record& r );        
};

istream& operator >> (istream& s,Record& r )
                    {       
                        s>>r.age;
                        s>>r.first_name;
                        s>>r.last_name;
                        return s;
                        }               
ostream& operator << (ostream& out,Record& r )
                    {
                        out << r.age ;
                        out << r.first_name ;
                        out << r.last_name ;
                        return out ;
                        }

These are the errors I am getting

SetMain.cpp: In function ‘int main()’:
SetMain.cpp:36:6: error: no match for ‘operator<<’ in ‘mm1 << mset’
SetMain.cpp:36:6: note: candidates are:
Set.cpp:111:10: note: template<class T> std::ostream& operator<<(std::istream&, MemSet<T>&)
Record.cpp:46:10: note: std::ostream& operator<<(std::ostream&, Record&)
Record.cpp:46:10: note:   no known conversion for argument 1 from ‘MemSet<MemSet<Record> >’ to ‘std::ostream& {aka std::basic_ostream<char>&}’
Parag
  • 662
  • 9
  • 15
  • 3
    Way too much code - why don't you narrow down the problem and post minimum code that displays the problem? – user93353 Aug 24 '13 at 10:07
  • ok , I wasn't very sure why error is there so I posted most of the part – Parag Aug 24 '13 at 10:13
  • @ParagJain - Learn to debug - enables one to narrow it down a little – Ed Heal Aug 24 '13 at 10:15
  • @EdHeal how can you debug a program which doesn't compile? – user93353 Aug 24 '13 at 10:23
  • Note that you used an `std::istream` in the output operator: it is just a copy and paste error in your templated output operator. – Dietmar Kühl Aug 24 '13 at 10:27
  • @Dietmar Kühl thanks for pointing it out , that happened while editing it in here....it is not there in code.. – Parag Aug 24 '13 at 10:38
  • Are you trying to print the contents of `mset` or add `mset` to `mm1`? – ilent2 Aug 24 '13 at 10:38
  • @ParagJain You can copy and paste code into here. After you paste it, just select it all and press Ctrl+K to indent. – ilent2 Aug 24 '13 at 10:39
  • @ilent2 ok, And I want to add the content to mm1..... – Parag Aug 24 '13 at 10:41
  • @user93353 - Easy comment bits out until it does then add a bits at a time. Alternatively write a function/method and compile that file. Then you will not end up with lots of code and have to spend ages finding out. Also read the error messages careful - all compilers to my knowledge tell you the line(s). Fix the first one on that list and try again. – Ed Heal Aug 24 '13 at 10:41
  • 1
    When you wrote `mm1 << mset;` did you mean `std::cout << mm1 << mset;`? Otherwise you need to define a shift operator taking a `MemSet>` and a `MemSet` as arguments (or templatized version thereof like `MemSet& operator<< (MemSet&, T const&);`. – Dietmar Kühl Aug 24 '13 at 10:46
  • @Dietmar Kühl no I do not want to write it to std::cout,I think that should work thanks, can you please tell how will I shift it as you suggested using templatized version? – Parag Aug 24 '13 at 11:04

2 Answers2

1

Adding 'mset' to 'mm1' using the syntax mm1 << mset instead of mm1.add(mset) can be done through:

template<typename T>
MemSet<T>& operator << (MemSet<T>& m, const T& v ) {
    m.add (v);
    return m;
}

Or equivalent

template<typename T>
class MemSet: public Set {
public:
    MemSet& operator << (const T& v ) {
        add (v);
        return *this;
    }
};

However, I'd be careful about CuteProgramming when adding "syntactic sugar" to your code like this.

such
  • 583
  • 4
  • 9
  • thanks that worked, can you suggest some good reference or tutorial on templates I need to add some more functions in this like overloading new and [] == for MemSet..... – Parag Aug 24 '13 at 11:18
  • There's an excellent walk through on the subject here at SO: [operator-overloading](http://stackoverflow.com/questions/4421706/operator-overloading) – such Aug 24 '13 at 11:49
1

Here is an example that provides behaviour similar to what I presume you want. You will need to extend the classes to provide comparison.

#include <iostream>
#include <vector>
#include <string>
using namespace std;

class Record
{
    friend istream& operator>> (istream& s, Record& r);
    friend ostream& operator<< (ostream& s, Record& r);

public:
    int GetAge(void) const { return m_nAge; }
    const std::string& GetFirstName(void) const { return m_strFirstName; }
    const std::string& GetLastName(void) const { return m_strLastName; }

private:
    int m_nAge;
    string m_strFirstName;
    string m_strLastName;
};

istream& operator>> (istream& s, Record& r)
{
    s >> r.m_nAge;
    s >> r.m_strFirstName;
    s >> r.m_strLastName;
    return s;
}

ostream& operator<< (ostream& s, Record& r)
{
    s << "Individual: " << r.m_strLastName << ", "
        << r.m_strFirstName << " (" << r.m_nAge << " years)" << endl;
    return s;
}

template<class T>
class MemSet : public vector<T>
{
    template<class T1>
    friend ostream& operator<< (ostream& s, MemSet<T1>& m);

    template<class T1>
    friend MemSet<T1>& operator<< (MemSet<T1>& m, T1& t);
};

template<class T>
ostream& operator<< (ostream& s, MemSet<T>& m)
{
    for (typename vector<T>::iterator it = m.begin(); it != m.end(); ++it)
        s << *it;
    return s;
}

template<class T>
MemSet<T>& operator<< (MemSet<T>& m, T& t)
{
    m.push_back(t);
    return m;
}

int main(int argc, char** argv)
{
    MemSet<Record> mset1, mset2;
    MemSet< MemSet<Record> > mm;
    Record temp;

    cin >> temp; mset1.push_back(temp);
    cin >> temp; mset1.push_back(temp);
    cin >> temp; mset1.push_back(temp);

    cin >> temp; mset2.push_back(temp);
    cin >> temp; mset2.push_back(temp);
    cin >> temp; mset2.push_back(temp);

    cout << mset1 << endl;

    mm << mset1;
    mm << mset2;

    cout << mm << endl;

    return 0;
}
ilent2
  • 5,171
  • 3
  • 21
  • 30