Re: How to create class template from class?
dd <dd.creazy@gmail.com> wrote:
Hello!
I have following class (and its work fine):
#include <set>
#include <algorithm>
#include <iostream>
using namespace std;
class mySet: public set<char> {
public:
mySet(): set<char>() {}
template <class Iterator>
mySet(Iterator first,Iterator last): set<char>(first,last) {} /
friend ostream& operator<<(ostream &out, const mySet &X);
mySet& operator+(mySet &X);
};
ostream& operator<<(ostream &out, const mySet &X) {
out<<"{";
for (set<char>::iterator i=X.begin();i!=X.end();i++) {
if (i!=X.begin()) out<<", ";
out<<*i;
}
out<<"}";
return out;
}
mySet& mySet::operator+(mySet &X) {
mySet returnValue;
set_union(this->begin(),this-
end(),X.begin(),X.end(),inserter(returnValue,returnValue.end()));
return returnValue;
}
As Christian already mentioned, the above is undefined behavior. If you
think it works fine, then that's just a coincidence. op+ needs to return
the result by value:
mySet mySet::operator+(const mySet& rhs) const;
the above is the correct declaration.
It is a container set<char> with overloaded operators: << and +.
I agree with Christian. Why make a a whole class just so you can
overload two operators that can't be used for any other container?
template <typename FwIt>
ostream& outputContainer(ostream& os, FwIt begin, FwIt end)
{
os << '{';
if (begin != end) {
os << *begin++;
while (begin != end) {
os << ", " << *begin++;
}
}
os << '}';
}
The above will work for every container that holds objects that can be
sent into a stream, and solves the issue at hand. Wouldn't you like to
be able to reuse this code rather than having to write it for each type
of container?
As for your other function, you are duplicating the functionality of
set_union, why not just use set_union?
Now I
would like to modify above code to create class template with
parameter T - a typ of elements of the set. I tried following code
(and it didn't work):
<cpp>
template <class T>
class mySet: public set<T> {
public:
mySet(): set<T>() {}
template <class Iterator>
mySet(Iterator first,Iterator last): set<T>(first,last) {} /
friend ostream& operator<<(ostream &out, const mySet<T> &X);
mySet<T>& operator+(mySet<T> &X);
};
template <class T>
ostream& operator<<(ostream &out, const mySet<T> &X) {
out<<"{";
for (set<char>::iterator i=X.begin();i!=X.end();i++) {
if (i!=X.begin()) out<<", ";
out<<*i;
}
out<<"}";
return out;
}
template <class T>
mySet<T>& mySet<T>::operator+(mySet<T> &X) {
mySet<T> returnValue;
set_union(this->begin(),this-
end(),X.begin(),X.end(),inserter(returnValue,returnValue.end()));
return returnValue;
}
</cpp>
How to achieve what I would like to achieve? Where I made mistakes? I
would be approciated for any help in this subject.
Remove the friend declaration from the class, there is no need for it.
Fix your op+ declaration in the class. Define your op+ correctly. Remove
the '/' after the constructor and don't put a line break in the middle
of the '->' token (if your news reader put this break in, then I suggest
judicious use of whitespace so that programs will be able to break up
your code intelligently.)
template <class T>
class mySet: public set<T> {
public:
mySet(): set<T>() {}
template <class Iterator>
mySet(Iterator first,Iterator last): set<T>(first,last) {}
mySet<T> operator+(const mySet<T> &X) const;
};
template <class T>
ostream& operator<<(ostream &out, const mySet<T> &X) {
out<<"{";
for (set<char>::iterator i=X.begin();i!=X.end();i++) {
if (i!=X.begin()) out<<", ";
out<<*i;
}
out<<"}";
return out;
}
template <class T>
mySet<T> mySet<T>::operator+(const mySet<T> &X) const {
mySet<T> returnValue;
set_union(begin(), end(), X.begin(), X.end(),
inserter(returnValue,returnValue.end()));
return returnValue;
}