0

I am working on some C++ homework and have hit a snag, I cannot run my displayList() function in my linkedlist class. I receive the following error.

Error 1 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'weatherstats' (or there is no acceptable conversion) c:\users\larry\documents\visual studio 2013\projects\weatherstats\weatherstats\linkedlist.h 100 1 WeatherStats

So I need to overload the << operand but I have tried using a few examples I found online but with no luck. Can someone help me with my << overload operator please?

EDIT: Added Weatherstats.cpp

EDIT 2: I created an overloaded << operand in my weatherstats.cpp file, I updated my content below. Instead of outputting my data, it outputs all data I enter as 1. I enter 2 for snow and it prints out 1 when using my displayList() function.

linkedlist.h

#pragma once

#include"WeatherStats.h"
#include<iostream>
#include<string>

using namespace std;


template <class T>
class linkedlist
{
private:

    struct ListNode
    {
        T value;                //Current value of node
        struct ListNode *next;  //Pointer to next node
    };

    ListNode *head;             //Head pointer

public:
    /*!
    Constructors
    !*/
    linkedlist()
    {
        head = NULL;
    };


    /*!
    Destructors
    !*/
    ~linkedlist();

    /*!
    Prototypes
    !*/
    void appendNode(T);         //Append a node to list
    void insertNode(T);         //Insert a node to list
    void deleteNode(T);         //delete a node in list
    void searchList(T);         //Search a node in list
    void displayList() const;           //Display the full list

    friend ostream &operator << (ostream&, linkedlist<T> &);
};


//**
//Append Node
//**
template <class T>
void linkedlist<T>::appendNode(T newValue)
{
    ListNode *newNode;          //Point to new node
    ListNode *nodePtr;          //Move through list

    //Assign newValue to new node
    newNode = new ListNode;
    newNode->value = newValue;
    newNode->next = NULL;

    if (!head)
    {   //If empty assign new node as head
        head = newNode;
    }
    else
    {   //Assign head to nodePtr
        nodePtr = head;

        //Find last node in list
        while (nodePtr->next)
        {
            nodePtr = nodePtr->next;
        }

        //Insert newNode as the last node
        nodePtr->next = newNode;
    }
}

//**
//Display List
//**

template <class T>
void linkedlist<T>::displayList()const
{

    ListNode *nodePtr;

    //Assign head to nodePtr
    nodePtr = head;

    //While nodePtr pointing to a node, print to screen
    while (nodePtr)
    {
        //Print value
        cout << nodePtr->value << endl; //ERROR C2679 HERE

        //Move nodePtr to next node
        nodePtr = nodePtr->next;
    }

}


//**
//Insert Node
//**
template <class T>
void linkedlist<T>::insertNode(T newValue)
{
    ListNode *newNode;
    ListNode *nodePtr;
    ListNode *previousNode = NULL;

    //New node
    newNode = new ListNode;
    newNode->value = newValue;

    //If list is empty assign newValue to head
    if (!head)
    {
        head = newNode;
        newNode->next = NULL;
    }
    else
    {
        //Assign head to nodePtr
        nodePtr = head;

        //Pass over all nodes who are less than newValue
        while (nodePtr != NULL && nodePtr->value < newValue)
        {
            previousNode = nodePtr;
            nodePtr = nodePtr->next;
        }

        //If new node will be first, insert before all other nodes
        if (previousNode == NULL)
        {
            head = newNode;
            newNode->next = nodePtr;
        }
        else
        {
            previousNode->next = newNode;
            newNode->next = nodePtr;
        }
    }
}


//**
//Delete Node
//**
template <class T>
void linkedlist<T>::deleteNode(T searchValue)
{

    ListNode *nodePtr;              //Traverse our list
    ListNode *previousNode = NULL;  //Points to previous node

    //Check if list is empty
    if (!head)
    {
        cout << "This list is empty." << endl;
        return;
    }

    //Delete head if == searchValue
    if (head->value == searchValue)
    {
        nodePtr = head->next;
        cout << head->value << " deleted" << endl;
        delete head;
        head = nodePtr;
    }

    else
    {
        //Set nodePtr to head
        nodePtr = head;

        //Skip nodes not equal num
        while (nodePtr != NULL && nodePtr->value != searchValue)
        {
            previousNode = nodePtr;
            nodePtr = nodePtr->next;
        }

        //Link previous node to the node after nodePtr and then delete
        if (nodePtr)
        {
            previousNode->next = nodePtr->next;
            cout << nodePtr->value << " deleted" << endl;
            delete nodePtr;
        }
    }
}


//**
//Search List
//**
template <class T>
void linkedlist<T>::searchList(T searchValue)
{
    ListNode *nodePtr;              //Traverse our list
    ListNode *previousNode = NULL;  //Points to previous node
    int counter = 0;

    //Check if list is empty
    if (!head)
    {
        cout << "This list is empty." << endl;
        return;
    }

    //Check if head == searchValue
    if (head->value == searchValue)
    {
        cout << head->value << " found at position 0" << endl;
    }

    else
    {

        //set nodePtr to head
        nodePtr = head;

        //Pass over all nodes that do not equal searchValue
        while (nodePtr != NULL && nodePtr->value != searchValue)
        {
            previousNode = nodePtr;
            nodePtr = nodePtr->next;
            counter++;
        }

        //When nodePtr == searchValue
        if (nodePtr)
        {
            cout << nodePtr->value << " found at position " << counter << endl;
        }

        else
        {
            cout << "-1: Value not found." << endl;
        }
    }
}


//**
//Destructor
//**
template <class T>
linkedlist<T>::~linkedlist()
{
    ListNode *nodePtr;   // To traverse the list
    ListNode *nextNode;  // To point to the next node

    // Position nodePtr at the head of the list.
    nodePtr = head;

    // While nodePtr is not at the end of the list...
    while (nodePtr != NULL)
    {
        // Save a pointer to the next node.
        nextNode = nodePtr->next;

        // Delete the current node.
        delete nodePtr;

        // Position nodePtr at the next node.
        nodePtr = nextNode;
    }
}




template <class T>
ostream &operator << (ostream stream, linkedlist<T> &obj)
{
    stream >> obj.value;

    return stream;
}

main.cpp

#include "linkedlist.h"
#include "WeatherStats.h"
#include <iostream>
#include <string>

using namespace std;

int main()
{
    int int_numMonths;      //Hold number of months value
    double dbl_rain;        //Hold rain value
    double dbl_snow;        //Hold snow value
    double dbl_sunnyDays;   //Hold sunny days value

    //Create lnk_list object with weatherstats
    linkedlist<weatherstats>weather_list;

    cout << "Weather Data" << endl;
    cout << endl;
    cout << "What is the number of months you want to enter data for?: ";
    cin >> int_numMonths;
    cout << endl;

    //Loop to enter each months values
    for (int i = 0; i < int_numMonths; i++)
    {
        cout << "Month " << i + 1 << endl;
        cout << "Enter amount of rain: " << endl;
        cin >> dbl_rain;
        cout << "Enter amount of snow: " << endl;
        cin >> dbl_snow;
        cout << "Enter number of Sunny Days: " << endl;
        cin >> dbl_sunnyDays;

        //Create weatherstats obj and pass it rain,snow and sunnyDays
        weatherstats month_data(dbl_rain,dbl_snow,dbl_sunnyDays);

        weather_list.appendNode(month_data);

    }

    weather_list.displayList();

}

Weatherstats.cpp

    #include "WeatherStats.h"

    #include <iostream>

    using namespace std;

    /*!
     Constructors
    !*/
    weatherstats::weatherstats()
    {
        dbl_rain = 0;
        dbl_snow = 0;
        dbl_sunnyDays = 0;
    }

    weatherstats::weatherstats(double r, double s, double d)
    {
        dbl_rain = r;
        dbl_snow = s;
        dbl_sunnyDays = d;
    }

    /*!
     Accessors
    !*/
    double weatherstats::getRain()
    {
        return dbl_rain;
    }

    double weatherstats::getSnow()
    {
        return dbl_snow;
    }

    double weatherstats::getsunnyDays()
    {
        return dbl_sunnyDays;
    }

    /*!
     Mutators
    !*/
    void weatherstats::setRain(double r)
    {
        dbl_rain = r;
    }

    void weatherstats::setSnow(double s)
    {
        dbl_snow = s;
    }

    void weatherstats::setsunnyDays(double d)
    {
        dbl_sunnyDays = d;
    }

//Overload Opperator
ostream& operator << (ostream &stream, weatherstats &obj)
{
    stream <<&weatherstats::getRain << " - " << &weatherstats::dbl_snow << " - " << &weatherstats::getsunnyDays << endl;
    return stream;
}
Dr-ZoidBerg
  • 41
  • 3
  • 10

2 Answers2

3

I'm going to take a stab in the dark with this, as I haven't touched templates or overloading for a couple of years.

Do you have the << operator overloaded for your weatherstats class?

Your error line is trying to print the value member variable. In your ListNode definition you say value is of type T (i.e. a template).

In your main() you are creating a linkedlist with your template type as weatherstats. Your error also states that it cannot convert the weatherstats type.

So the question is: Are you Overloading << for the weatherstats class ?

Unfortunately, you haven't posted the code for this class, so we can't go any further than this. Edit: Code has been posted - still no evidence of overloading

(Also I think Baget makes a good point about the direction of your stream operator later on)

EDIT2: How should you call a function? Is it &classname::function or object.function()?

Community
  • 1
  • 1
DiJuMx
  • 524
  • 5
  • 10
  • DiJuMx, I added my weatherstats.cpp file, I did not include the header file, if you want to see that as well please let me know. – Dr-ZoidBerg Apr 20 '14 at 21:49
  • 1
    Like I said in my answer, I can't see any evidence that you've overloaded the `<<` operator for the `weatherstats` class. This is where your error is coming from. If it's in the header file then it would be useful to see. – DiJuMx Apr 20 '14 at 22:10
  • To clarify a little more: the error is not directly related to `class linkedlist` at all. `nodePtr->value` is of type `weatherstats`, but the compiler can't see a function anything like `operator<<(std::ostream&, const weatherstats&)`. – aschepler Apr 20 '14 at 22:28
  • I am stupid, I didn't comprehend your answer when reading it DiJuMx. Let me overload << in weatherstats class and try it out. Thank you as well aschepler. – Dr-ZoidBerg Apr 20 '14 at 23:06
  • @DijuMx I am having a hard time adding the << overload to my weatherstats .h and .cpp. Can you provide me with an example on how it should be done?When using the operand overload in my linkedlist class it is stream >> obj.value. There is no value of a linkedlist node in my weatherstats class. – Dr-ZoidBerg Apr 20 '14 at 23:24
  • as aschepler says, something like `operator<<(std::ostream&, const weatherstats&)`. As this is a homework task, I'm not going to do the work for you. You probably have notes on this topic (you also have google). By overloading `<<` you are specifying how the variables inside the class are output to a stream. e.g. `"Temperature: " << obj.temp << "Humidity: " << obj.humid <<"%";` etc – DiJuMx Apr 20 '14 at 23:31
0

isn't stream >> obj.value; need to be stream<<obj.value;

it is OUTPUT stream not INPUT

Baget
  • 3,318
  • 1
  • 24
  • 44