Перегрузка оператора << в связанном списке - PullRequest
1 голос
/ 13 октября 2009

Как мне перегрузить operator <<. Целью перегруженного оператора является: cout << ptr->info и не получает адрес памяти, но отображает год производителя и модель информационной секции этого узла.

Пример:

template <class DataType>
struct Node {
DataType info;
Node<DataType> *next;
};

В каждом разделе информации узла будет такая структура:

struct Car {
    string maker;
    string year;
    string model;
}

Пока у меня есть это, но, похоже, оно не работает:

friend ostream &operator << ( ostream &output, Node<DataType> &rlist ) { //Overloaded <<
    output << rlist->info.make << endl;
    output << rlist->info.year << endl;
    output << rlist->info.price << endl; 

    return output;
}  

Когда я компилирую с g ++, я получаю эту ошибку:

LinkedList.cpp: In member function ‘void LinkedList<DataType>::EscribaUltimo() [with DataType = CarType]’:
main.cpp:37:   instantiated from here
LinkedList.cpp:15: error: no match for ‘operator<<’ in ‘std::cout << ptr->Node<CarType>::info’

Ответы [ 3 ]

2 голосов
/ 13 октября 2009

Хотя я немного запутался, потому что вы на самом деле основной код отсутствует. Я собираюсь предположить, что у вас есть узел от обхода ссылки, и теперь вы хотите напечатать его:

#include <iostream>
#include <string>

using namespace std; // not recommended, but useful
                     // in snippets

// T is usually used, but this is of course up to you
template <class T> 
struct Node
{
    typedef T value_type; // a usual typedef

    value_type info;
    Node<value_type> *next;
};

struct Car
{
    string maker;
    string year;
    string model;
}; // you had a missing ;, probably copy-paste error

// this creates a node. normally you'd want this to be
// wrapped into a list class (more on this later)
template <typename T>
Node<T> *createNode(const T& info = T())
{
    // allocate node
    Node<T> *result = new Node<T>;
    result->info = info;
    result->next = 0; // no next

    return result; // returning a pointer means
                   // whoever gets this is
                   // responsible for deleting it!
}

// this is the output function for a node
template <typename T>
std::ostream& operator<<(std::ostream& sink, const Node<T>& node)
{
    // note that we cannot assume what node contains!
    // rather, stream the info attached to the node
    // to the ostream:
    sink << node.info;

    return sink;
}

// this is the output function for a car
std::ostream& operator<<(std::ostream& sink, const Car& car)
{
    // print out car info
    sink << "Make: " << car.maker <<
            "\nYear: " << car.year <<
            "\nModel: " << car.model << std::endl;

    return sink;
}

int main(void)
{
    // a car list
    typedef Node<Car> CarList;

    // a couple cars
    Car car1 = {"Dodge", "2001", "Stratus"};
    Car car2 = {"GMan's Awesome Car Company", "The future", "The best"};

    CarList *head = createNode(car1); // create the first node
    head->next = createNode(car2);

    // now traverse the list
    CarList *iter = head;
    for (; iter != 0; iter = iter->next)
    {
        // output, dereference iterator to get the actual node
        std::cout << "Car: " << *iter << std::endl;
    }

    // dont forget to delete!
    iter = head;
    while (iter)
    {
        // store next
        CarList *next = iter->next;

        // delete and move on
        delete iter;
        iter = next;
    }
}

Теперь, если вам не нужно создавать свой собственный список ссылок, используйте вместо него стандартный список ссылок, это значительно упростит вашу задачу:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <list>
#include <string>

using namespace std;

struct Car
{
    string maker;
    string year;
    string model;
};


// this is the output function for a car
std::ostream& operator<<(std::ostream& sink, const Car& car)
{
    // print out car info
    sink << "Make: " << car.maker <<
            "\nYear: " << car.year <<
            "\nModel: " << car.model << std::endl;

    return sink;
}

int main(void)
{
    // a car list
    typedef std::list<Car> CarList;

    // a couple cars
    Car car1 = {"Dodge", "2001", "Stratus"};
    Car car2 = {"GMan's Awesome Car Company", "The future", "The best"};

    CarList cars;
    cars.push_back(car1);
    cars.push_back(car2);

    // now traverse the list (copy to ostream)
    std::copy(cars.begin(), cars.end(),
             std::ostream_iterator<Car>(std::cout,"\n"));

    // delete done automatically in destructor
}

Надеюсь, это поможет.

1 голос
/ 13 октября 2009

Просто чтобы убедиться, что у вас есть

template<class DataType>

до определения оператора, верно? Если я это сделаю, это работает для меня. Сообщения об ошибках показывают номера строк в вашем коде, но где они находятся в вставленных определениях? Читая это, я думаю, что проблема не с

Node<DataType> myNode;
output << myNode 

но с

output << myNode.info

без оператора <<, определенного для него. </p>

Редактировать: По вашему комментарию, вы хотите определить оператора << для автомобиля. Итак, я бы сделал (не проверено) </p>

ostream& operator<< (ostream& output, Car& car) {
  output << car.foo << end;
  output << car.bar << end;
  return output;
}

template <class DataType>
ostream& operator<< (ostream& output, Node<DataType>& node ) {
  output << node.info << end;
  return output;
}

По сути, это означает, что когда вы специализируете свой тип Node и хотите использовать для него оператор <<, вам необходимо убедиться, что для DataType, на котором вы специализируетесь, также определен оператор <<. </p>

0 голосов
/ 13 октября 2009

Вам нужно два оператора: один для узла (или Node*) и один для автомобиля:

ostream &operator << ( ostream &output, Car &car ) {
    output << car.maker << endl;
    output << car.year << endl;
    output << car.model << endl; 
    return output;
}

template<class DataType>
ostream &operator << ( ostream &output, Node<DataType> *rlist ) {
    output << rlist->info;
    return output;
}
...