By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,007 Members | 1,045 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,007 IT Pros & Developers. It's quick & easy.

Problem overriding >> and << in a template class

P: n/a
hello people i. can anybody help me, i dont know what is wrong with
this class. it has something to do with the me trying to override the
input output stream. if i dont override it, it works fine. i would
forget overriding it but i have to do it because its a coursework. here
is a simple version of the class
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
template <typename Item>
class Sample {
private:
vector<Item> results;

public:
Sample(vector<Item> samps);

const vector<Item> get_data();

void set_data(const vector<Item> &v);

long double minimum();

long double maximum();

friend ostream& operator<<(ostream& os, const Sample& samp);

friend istream& operator>>(istream& is, Sample& samp);

};

template <typename item>
Sample<item>::Sample(vector<item> samps) : results(samps) {}

template <typename item>
const vector<item> Sample<item>::get_data(){
return results;
}

template <typename item>
void Sample<item>::set_data(const vector<item> &v) {
results = v;
}

template <typename item>
long double Sample<item>::minimum(){
long double m;
for(int i = 0; i < results.size(); i++){
if(i == 0){
m = results[i];
}else if(results[i] < m){
m = results[i];
}
}

return m;
}

template <typename item>
long double Sample<item>::maximum(){
long double m;
for(int i = 0; i < results.size(); i++){
if(i == 0){
m = results[i];
}else if(results[i] > m){
m = results[i];
}
}

return m;
}

template <typename item>
ostream&
operator<<(ostream& os, const Sample<item>& samp){
cout << "<" << samp.results.size() << ":";

for(int i = 0; i < samp.results.size(); i++){
cout << " " << samp.results[i];
}

cout << " >";
return os;
}

template <typename item>
istream&
operator>>(istream& is, Sample<item>& samp){
string s;
int count = 0;
int size;
while (is >> s){
if(count == 0 && s[0] == '<' && s[s.size()-1] == ':'){
//size = parseInt(s.substr(0,s[s.size()-2]));
size = atoi((s.substr(1,s.size()-2)).c_str());

cout << "begin size = " << size << endl;
}else if(s[s.size()-1] == '>'){
//size = parseInt(s.substr(0,s[s.size()-1]));
cout << "end " << endl;
count = 0;
break;
}else {
//size = parseInt(s.substr(0,s[s.size()-1]));
cout << count << " " << atof(s.c_str()) << endl;
samp.results.push_back(atof(s.c_str()));
}
count++;
}
return is;
}

int main(){

vector<double> a;

a.push_back(7);
a.push_back(11);
a.push_back(2);
a.push_back(13);
a.push_back(3);
a.push_back(5);

//string s;
Sample<double> samp(a);
while (cin >> samp){

cout << samp.minimum() << endl << samp.maximum() << endl;

}

cout << samp;

return 0;
}
Any help will be greatly appreciated

Jul 23 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
fr*******@hotmail.com wrote:
hello people i. can anybody help me,


Interestingly, this looks very much like an article I recently rejected
from comp.lang.c++.moderated because it uses excessive code, i.e. it
includes loads of stuff entirely irrelevant to the question. Of course,
the rejection also mentioned the cause the of problem: The functions
you declare friends within the body of the class are non-template
functions and, except for the same name, entirely unrelated to the
function templates you use later!

For the friend functions to work correctly you need to declare them
*prior* to the class definition which in turn means that you also need
to forward declare the class definition itself. In addition, you need
to use a template argument list in the friend declaration. However,
since the template arguments can actually be deduced from the function
arguments, this template argument list can be empty. It just has to be
present to indicate that the function template is made a friend. The
whole code would look something like this:

#include <iostream>

template <typename> class foo;
template <typename T>
std::ostream& operator<< (std::ostream&, foo<T> const&);

template <typename T>
struct foo
{
foo(): val(17) {}
// ...
friend std::ostream& operator<< <>(std::ostream&, foo<T> const&);
private:
int val;
};

template<typename T>
std::ostream& operator<< (std::ostream& os, foo<T> const& f)
{
return os << f.val;
}

int main()
{
std::cout << foo<int>() << "\n";
}

BTW, this is not "overriding" the output operator but "overloading".
There is signification difference between these two terms although
they look very similar. Overriding is the term used to indicate that
a virtual function of a base class is, well, overridden by a derived
class, i.e. it is the mechanism used to implement dynamic polymorphism.
The overridden function has essentially the same signature as the
original on (although the return type may be covariant; theoretically
the arguments could be contravariant but this is not supported by C++).
Overloading on the other means that the same function name is used for
an otherwise unrelated function: the signatures of overloaded functions
vary be definition and there is no dynamic polymorphism involved. Of
course, the unrelated functions should to similar things when they
share a common name but this is technically not required.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

Jul 23 '05 #2

P: n/a
thanks a lot for the help, i tried it and it worked. i really
appreciate it and God bless you.
franky

Jul 23 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.