New to c++, need help with a template class

F

franklini

i cant seem to figure out what is wrong with this class. it has to do
with the input/output stream override. please can somebody help me.

#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();

long double range();

long double midrange();

long double mean();

long double variance();

long double std_deviation();

//get the index of the current minimum double in the vector
int minimum2(vector<Item> v);

//get the number which i currently the smallest in the
//given vector
long double minimum3(vector<Item> v);

long double median();

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;
}else if(results < m){
m = results;
}
}

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;
}else if(results > m){
m = results;
}
}

return m;
}

template <typename item>
long double Sample<item>::range(){
long double max = maximum();
long double min = minimum();
long double range = max - min;
return range;
}

template <typename item>
long double Sample<item>::midrange(){
long double max = maximum();
long double min = minimum();
long double mid_range = (max + min)/2.0;
return mid_range;
}

template <typename item>
long double Sample<item>::mean(){
long double sum = 0;
long double m;
for(int i = 0; i < results.size(); i++){
sum += results;
}
m = sum/(results.size() * 1.0);

return m;
}

template <typename item>
long double Sample<item>::variance(){
long double sum = 0;
long double m = mean();

for(int i = 0; i < results.size(); i++){
sum = sum + (pow(results-m,2));
}
return sum/(results.size() * 1.0);
}

template <typename item>
long double Sample<item>::std_deviation(){
sqrt (variance());
}

//get the index of the current minimum double in the vector
template <typename item>
int Sample<item>::minimum2(vector<item> v){
double m;
int k = 0;
for(int i = 0; i < v.size(); i++){
if(i == 0){
m = v;
k = i;
}else if(v < m){
m = v;
k = i;
}
}

return k;
}

//get the number which i currently the smallest in the
//given vector
template <typename item>
long double Sample<item>::minimum3(vector<item> v){
long double m;
for(int i = 0; i < v.size(); i++){
if(i == 0){
m = v;
}else if(v < m){
m = v;
}
}

return m;
}

template <typename item>
long double Sample<item>::median(){

vector <item> ordered_results;
vector <item> current_results = results;

int index;
int s = current_results.size();

for(int i = 0; i < s; i++){
index = minimum2(current_results);

//push the current minimum into our new array;
ordered_results.push_back(current_results[index]);

//remove that value from the array
for(vector<item>::iterator k = current_results.begin(); k !=
current_results.end(); ++k){
if (*k == minimum3(current_results)){
current_results.erase(k);
break;
}
}
}

if (ordered_results.size()%2 == 1){
int g = (ordered_results.size()/2);
return ordered_results[g];

}else{
return (ordered_results[(ordered_results.size()/2)-1] +
ordered_results[(ordered_results.size()/2)])/2.0;

}

}

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

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

cout << " >";


return os;
}

template <typename item>
istream&
Sample<item>::eek:perator>>(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;
double h1 = 1.7976931348623158e+308;
double h2 = 1.7976931348623158e+308;
a.push_back(h1);
a.push_back(h2);
a.push_back(h2);
//string s;


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

cout << samp.minimum() << endl << samp.maximum() << endl
<< samp.range() << endl << samp.midrange() << endl
<< samp.mean() << endl << samp.variance() << endl
<< samp.std_deviation() << endl << samp.median() << endl;

}

cout << samp;

return 0;
}
 
V

Victor Bazarov

i cant seem to figure out what is wrong with this class.

Then how do you know that something *is* wrong with it? :)

Please be more specific when describing your problem next time.
it has to do
with the input/output stream override. please can somebody help me.

[...]

template <typename item>
ostream&
Sample<item>::eek:perator<<(ostream& os, const Sample<item>& samp){

This operator cannot be a member. It has to be a stand-alone function.
IOW, drop the "Sample<item>::" prefix. Instead it should be

template<typename item>
ostream& operator said:
cout << "<" << samp.results.size() << ":";

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

cout << " >";


return os;
}

template <typename item>
istream&
Sample<item>::eek:perator>>(istream& is, Sample<item>& samp){


Same here, make it a stand-alone function.
 
F

franklini

It know looks like this and it still doesnt compile.

#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();

long double range();

long double midrange();

long double mean();

long double variance();

long double std_deviation();

//get the index of the current minimum double in the vector
int minimum2(vector<Item> v);

//get the number which i currently the smallest in the
//given vector
long double minimum3(vector<Item> v);

long double median();

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;
}else if(results < m){
m = results;
}
}

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;
}else if(results > m){
m = results;
}
}

return m;
}

template <typename item>
long double Sample<item>::range(){
long double max = maximum();
long double min = minimum();
long double range = max - min;
return range;
}

template <typename item>
long double Sample<item>::midrange(){
long double max = maximum();
long double min = minimum();
long double mid_range = (max + min)/2.0;
return mid_range;
}

template <typename item>
long double Sample<item>::mean(){
long double sum = 0;
long double m;
for(int i = 0; i < results.size(); i++){
sum += results;
}
m = sum/(results.size() * 1.0);

return m;
}

template <typename item>
long double Sample<item>::variance(){
long double sum = 0;
long double m = mean();

for(int i = 0; i < results.size(); i++){
sum = sum + (pow(results-m,2));
}
return sum/(results.size() * 1.0);
}

template <typename item>
long double Sample<item>::std_deviation(){
sqrt (variance());
}

//get the index of the current minimum double in the vector
template <typename item>
int Sample<item>::minimum2(vector<item> v){
double m;
int k = 0;
for(int i = 0; i < v.size(); i++){
if(i == 0){
m = v;
k = i;
}else if(v < m){
m = v;
k = i;
}
}

return k;
}

//get the number which i currently the smallest in the
//given vector
template <typename item>
long double Sample<item>::minimum3(vector<item> v){
long double m;
for(int i = 0; i < v.size(); i++){
if(i == 0){
m = v;
}else if(v < m){
m = v;
}
}

return m;
}

template <typename item>
long double Sample<item>::median(){

vector <item> ordered_results;
vector <item> current_results = results;

int index;
int s = current_results.size();

for(int i = 0; i < s; i++){
index = minimum2(current_results);

//push the current minimum into our new array;
ordered_results.push_back(current_results[index]);

//remove that value from the array
for(vector<item>::iterator k = current_results.begin(); k !=
current_results.end(); ++k){
if (*k == minimum3(current_results)){
current_results.erase(k);
break;
}
}
}

if (ordered_results.size()%2 == 1){
int g = (ordered_results.size()/2);
return ordered_results[g];

}else{
return (ordered_results[(ordered_results.size()/2)-1] +
ordered_results[(ordered_results.size()/2)])/2.0;

}

}

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

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

cout << " >";


return os;
}

template <typename item>
istream&
operator>> <item>(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
<< samp.range() << endl << samp.midrange() << endl
<< samp.mean() << endl << samp.variance() << endl
<< samp.std_deviation() << endl << samp.median() << endl;

}

cout << samp;

return 0;
}


thanks for you time
 
V

Victor Bazarov

It know looks like this and it still doesnt compile.

[...]
template <typename item>
long double Sample<item>::std_deviation(){
sqrt (variance());

Should probably be

return sqrt(variance());
}

[...]
template <typename item>
ostream&
operator<< <item>(ostream& os, const Sample<item>& samp){

My mistake. Drop the first <item>. Make it

operator << (ostream& os, const Sample<item>& samp) {

(and the other one too).


It should compile now, but probably won't link (it didn't for me).
You're on your own to find the missing function implementations.

V
 
F

franklini

Thanks anyway for your help. made the change and it does compile but
doesnt link. this is a coursework and i just dont know what is wrong
with it. its driving me crazy.
 
L

Larry Brasfield

Thanks anyway for your help. made the change and it does compile but
doesnt link. this is a coursework and i just dont know what is wrong
with it. its driving me crazy.


It should drive you to implement the missing function(s)
about which the linker is undoubtedly complaining.
The code I've seen merely *declared* a template
function. That allows the compiler to process a
call to the function. Without actually *defining*
the function, there is nothing to actually *call*,
and that fact is finally evident only at link time.

Either your prof provided the definitions, you are
supposed to write the function, or the prof has made
a mistake of some kind. One mistake, unless you have
been asleep in or missing from class, was to never
explain the roles and purposes of the compiler and linker.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top