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

Discussion in 'C++' started by franklini@hotmail.com, Mar 1, 2005.

  1. Guest

    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;
    }
    , Mar 1, 2005
    #1
    1. Advertising

  2. wrote:
    > 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<< <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&
    > Sample<item>::eek:perator>>(istream& is, Sample<item>& samp){


    Same here, make it a stand-alone function.

    > [...]
    Victor Bazarov, Mar 1, 2005
    #2
    1. Advertising

  3. Guest

    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
    , Mar 1, 2005
    #3
  4. wrote:
    > 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
    Victor Bazarov, Mar 1, 2005
    #4
  5. Guest

    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.
    , Mar 1, 2005
    #5
  6. <> wrote in message
    news:...
    > 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.

    --
    --Larry Brasfield
    email:
    Above views may belong only to me.
    Larry Brasfield, Mar 1, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page