2

I'm trying to overload << . No luck so far. Here's my overload implementation:

struct Engineer{
    int id;
    int salary;
    bool hired;
public:
    Engineer(int _id, int _salary) : id(_id), salary(_salary), hired(false) {}

    std::ostream& operator<<(std::ostream& os)
    {
      return os << " " << id << std::endl;
    }
};

and here's me trying to use it:

void inorderTravel(AvlNode* root) {
    if(root == NULL) return;
    inorderTravel(root->left);
    std::cout << root->data;     // <- here
    inorderTravel(root->right);
}

the line "std::cout << root->data;" evokes all the errors:

> Multiple markers at this line
>   - cannot convert 'root->AvlTree<Engineer,    IdKey>::AvlNode::data' (type 'Engineer') to type 'unsigned char'
>   - cannot convert 'root->AvlTree<Engineer,    IdKey>::AvlNode::data' (type 'Engineer') to type 'signed char'
>   - 'Engineer' is not derived from 'const std::basic_string<_CharT,    _Traits, _Alloc>'
>   - cannot convert 'root->AvlTree<Engineer,    IdKey>::AvlNode::data' (type 'Engineer') to type 'char'
>   - deduced conflicting types for parameter '_CharT' ('char' and       'Engineer')
>   - no match for 'operator<<' (operand types are 'std::ostream {aka    std::basic_ostream<char>}' and 'Engineer')
>   - candidates are:
>   - cannot convert 'root->AvlTree<Engineer,    IdKey>::AvlNode::data' (type 'Engineer') to type 'const char*'
>   - mismatched types 'const _CharT*' and 'Engineer'
>   - cannot convert 'root->AvlTree<Engineer,    IdKey>::AvlNode::data' (type 'Engineer') to type 'const unsigned char*'
>   - cannot convert 'root->AvlTree<Engineer,    IdKey>::AvlNode::data' (type 'Engineer') to type 'const signed char*'
Mat
  • 202,337
  • 40
  • 393
  • 406
Bob Sacamano
  • 699
  • 15
  • 39

2 Answers2

2

You defined the operator std::ostream& Engineer::operator<<(std::ostream&) - so the left operand of an expression like left << right must be of type Engineer and the right operand of type std::ostream&...

You can define the right operator as a friend function in your Engineer class like so:

friend std::ostream& operator<<(std::ostream& out, Engineer const& self)
{ return out << " " << self.id << std::endl; }
danielschemmel
  • 10,885
  • 1
  • 36
  • 58
  • *left argument* seems a little bit misleading – Wolf Apr 27 '14 at 15:19
  • @Wolf clarified the meaning – danielschemmel Apr 27 '14 at 15:23
  • What about changing the order: Solution first, details about the failing approach later? I find that the focus lies to much on the wrong thing in the [current version of answer](http://stackoverflow.com/revisions/23325060/2). – Wolf Apr 28 '14 at 10:16
  • @Wolf There are a great many discussions of how to properly overload the streaming operators already out there. Therefore the explanation of what fails about the OPs attempt seems more important to me. – danielschemmel Apr 28 '14 at 14:42
1

This is not a correct definition of operator<<. This operator should take as second argument a const reference to an instance of the class you are trying to print. Using your definition there is an implicit first argument. An operator<< can not be defined in a class, typically it is implemented as a friend function. Something like this:

struct Engineer{
  //... other code
  friend std::ostream& operator<<(std::ostream& os, const Engineer& e);
};

std::ostream& operator<<(std::ostream& os, const Engineer& e)
{
  return os << " " << id << std::endl;
}
Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
  • *An operator<< can not be defined in a class* - is this the whole truth? And, if yes, why? – Wolf Apr 28 '14 at 10:19
  • @wolf From OP's question the idea is to use `operator<<` to output to a stream. If that is what is needed, the operator should be declared in the way I describe. This means that the first argument of this operator should be an `ostream&` and as all class methods have an implicit first argument of the class type it is not possible to declare such method within the class. An `operator<<` with other operand types can still be declared but it will not be used in the case OP describes. – Ivaylo Strandjev Apr 28 '14 at 11:14