-1

Added override for operator<< for my class but i am getting inside a function:

error: no match for ‘operator<<’ (operand types are ‘std::basic_ostream’ and ‘Edge’)

cout << "Adding: " << edge;

But if i try to use this code everything works as expected:

  Edge edge1("A", "B", 3);
  Edge* edge2 = new Edge("A", "B", 3);
  cout << edge1 << endl;
  cout << *edge2 << endl;

Here is code:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Node {
  public:
  string name;
  Node() {}
  Node(string name):name(name) {}

  bool operator==(const Node& other) {
    return name == other.name;
  }
};

class Edge {
  public:
  Node x;
  Node y;
  int cost;
  Edge(string x_name, string y_name, int cost) {
    this->x = Node(x_name);
    this->y = Node(y_name);
    this->cost = cost;
  }
  Edge(Node x, Node y, int cost):x(x),y(y) {}

  bool operator==(const Edge& other) {
    return x == other.x && x == other.y && cost == other.cost;
  }
};

class Graph {
  public:
  vector<Edge> edges;
  vector<Node> nodes;

  bool has_node(Node node) {
    return find(nodes.begin(), nodes.end(), node) != nodes.end();
  }

  bool has_edge(Edge edge) {
    return find(edges.begin(), edges.end(), edge) != edges.end();
  }

  void add(string x_name, string y_name, int cost) {
    Node x(x_name);
    Node y(y_name);
    bool has_not_x = !has_node(x);
    bool has_not_y = !has_node(y);
    if (has_not_x) {
      nodes.push_back(x);
    }
    if (has_not_y) {
      nodes.push_back(y);
    }
    if (has_not_x || has_not_y) {
      add(x, y, cost);
    }
  }

  void add(Node x, Node y, int cost) {
    Edge edge(x, y, cost);
    if (!has_edge(edge)) {
      cout << "Adding: " << edge;
      edges.push_back(edge);
    }
  }
};

ostream& operator<<(ostream& os, const Node& node)
{
    os << "(" << node.name << ")";
    return os;
}

ostream& operator<<(ostream& os, const Edge& edge)
{
    os << edge.x << "-" << edge.cost << "-" << edge.y;
    return os;
}

int main()
{
  Graph* graph = new Graph();
  graph->add("A", "C", 1);

  return 0;
}
Community
  • 1
  • 1
ambi
  • 35
  • 1
  • 1
  • 9
  • Is this the order in youe code? Then you are trying to use the operator before it is defined. – Bo Persson Feb 04 '17 at 22:30
  • 2
    The attempted assertion occurs at a point where the `<<` operator has not yet been declared. Move that definition of `Graph::add` outside the definition of `Graph` and put it after the definition of `operator <<`. – Pete Becker Feb 04 '17 at 22:30
  • Pete Becker, thank you that worked – ambi Feb 04 '17 at 22:33
  • "if i try to use this code everything works as expected" - Really? If you replace the line of code that is tripping an error with the code you say works, it just starts working? Somehow i doubt that. The code you say "works" is no-doubt not in the `add` function when you tested it, and *after* the `operator<<` being used has been seen by the compiler. That's a strong hint what is wrong. – WhozCraig Feb 04 '17 at 22:34
  • You could also forward declare the classes and add prototypes for the functions before you try to use them. – Retired Ninja Feb 04 '17 at 22:34
  • Where is your [MCVE]? – Lightness Races in Orbit Feb 04 '17 at 22:51

1 Answers1

1

Because the compiler reads the code linearly, it is not aware that the overload of operator<<(ostream&, const Edge&) exists yet.

If you place a declaration of the overload before the definition of the class, the code will compile:

// Place the function declaration before the class
// to inform the compiler of the overload's existence.
ostream& operator<<(ostream& os, const Edge& edge);

class Graph {
    public:
        vector<Edge> edges;
        vector<Node> nodes;
// and so on...
CinchBlue
  • 6,046
  • 1
  • 27
  • 58