Unrecognized << operator overload

Problem Statement:
I'm working through the Towers of Hanoi puzzle. In creating the Game class, I'm using an overloaded << operator to output the contents of the stacks. The compiler doesn't seem to be recognizing the overloaded operator at all, however, giving me the error "error: no match for ‘operator<<’ (operand types are ‘std::basic_ostream<char>’ and ‘const value_type’ {aka ‘const std::stack<Cube>’})
os << "Stack[" << i << "]: " << game.stacks_[i];

Header file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef GAME_H
#define GAME_H
#include"cube.h"
#include<stack>
#include<vector>
#include<ostream>

     class Game
     {
          public:
               Game();
               void solve();

               friend std::ostream& operator<< (std::ostream & os, const Game & game); //Problematic statement

          private:
               std::vector<std::stack<Cube>> stacks_;
     };
     #endif


Code segment in cpp file:
1
2
3
4
5
6
7
8
 std::ostream& operator<< (std::ostream & os, const Game & game)
     {
          for (int i = 0; i < game.stacks_.size(); i++)
          {
               os << "Stack[" << i << "]: " << game.stacks_[i];
          }
          return os;
     }


I've tried explicitly defining the implementation as a member of the Game class, which fixes the first problem, but introduces issues with implicit arguments, I've tried declaring it as a basic member function, which breaks even more stuff, and I;ve even gone so far as to cheat against a working copy of the code, which looks exactly like mine as far as I can tell. At this point, I'm stumped and could use some advice.

I have considered simply writing a print function that would output what I need, but from everything I can tell, this *should* work, and I would like to know why it isn't.

Followup question: What is the reason behind this function returning an ostream object?

Compiler: g++ Debian 8.2.0
Last edited on
What do you want to be printed when you "cout <<" a stack<Cube>?
This needs to be defined somewhere

1
2
3
4
5
std::ostream& operator<<(std::ostream & os, const std::stack<Cube>& cube_stack)
{
          // CODE HERE
          return os;
}


Followup question: What is the reason behind this function returning an ostream object?
This allows chaining the << operator:
cout << item1 << item2 << item3 << ...
Without it, you could only do:
cout << item1;
Last edited on
The output for this operator should print the Game object (a vector of 3 stack<Cube>s).

Ideally it should look like this:

Stack(0): 4 3 2 1 (Num in parentheses is vector index, ints represent the cubes in each stack)
Stack(1):
Stack(2):

For the starting position of the game.

I anticipated that the internals of the overloaded operator weren't correct, and would need fiddling. I'm just confused by why the compiler doesn't seem to recognize that I've declared an overloaded operator in the first place?
You've written the function for how to print a Game object. That's good. But the issue is that your Game object contains std::stack<Cube> objects, and you're passing these to be printed.

The compiler doesn't have a built-in way to print std::stack<Cube> object; you must define it.

Ideally it should look like this:
Stack(0): 4 3 2 1
Okay, but the logic for this needs to exist somewhere for your code to compile. Right now, you're trying to print an std::stack<Cube>, and it has no idea how to do that, because you haven't told it how to.

From what you've shown, all I can see is that the compiler doesn't know how to handle the << operator when used with an ostream and an std::stack<Cube>.

This means that there is no std::ostream& operator<<(std::ostream& os, const std::stack<Cube>& cube_stack) function defined in your code. This is what is needed on line 5 of your second code excerpt -- you're passing game.stacks_[i] to be printed.

e.g.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <stack>

class Foobar { };

std::ostream& operator<<(std::ostream& os, const std::stack<Foobar>& foobar)
{
    return os << "(in custom operator for stack<Foobar>), stack.size == " << foobar.size();   
}

int main()
{
  std::stack<Foobar> my_stack;
  my_stack.push(Foobar());
  my_stack.push(Foobar());
  
  std::cout << my_stack << '\n';
}

(in custom operator for stack<Foobar>), stack.size == 2

______________________________________________

You need to define two different operator<< functions.
1. To be able to print the Game object.
2. To be able to print each std::stack<Cube> within the game object.
Last edited on
Ah! I see! I was interpreting the error as relating to the Game object, not the Stack object! I will fix that later tonight! Thank you!
This is where it helps to slow down, and take the time to read the error message carefully.

In particular, the line number would have indicated clearly that the error was on line 5 of your second snippet, i.e. the line inside the operator for Game, that is trying to stream game.stacks_[i].
Last edited on
Topic archived. No new replies allowed.