too many parameters for this operator function

I have declared a overloaded version of the chevron operator within my Book class. But i keep getting the error :

too many operators for this operator function.


ostream& operator<<(ostream& os, Book& dt)
{
os << dt.getAuthor() << '/' << dt.getIsbn() << '/' << dt.getPrice() << '/' << dt.getTitle() << endl;
return os;
}





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
 
#pragma once
#include <string>

using namespace std; 

class Book {

private:

	string author_ = "unknown";
	int isbn_ = 0;
	int price_ = 0;
	string title_ = "unknown";


public:


	// once you implement the 4 - args constructor, the synthesized default constructor gets overridden
	// so you need to implement a default constructor by urself
	// default constructor

	Book() {
		author_ = "unknown";
		isbn_ = 0;
		price_ = 0;
		title_ = "unknown"; 
	}

	// 4- args constructor 
	Book(string author, int isbn, int price, string title) : author_(author), isbn_(isbn), price_(price), title_(title)  {}

	// does not work , need to make Book as a reference
	//Book( Book orig) : author_(orig.author_), isbn_(orig.isbn_), price_(orig.price_), title_(orig.title_) {}

	// notice how there is a reference sign infront of Book
	Book(Book const&  orig) : author_(orig.author_), isbn_(orig.isbn_), price_(orig.price_), title_(orig.title_) {}


	// move constructor 
	Book(Book && orig) : author_(std::move(orig.author_)), isbn_(std::move(orig.isbn_)), price_(std::move(orig.price_)), title_(std::move(orig.title_)) {}




	string getAuthor()  {

		return author_;

	}


	string getTitle()  {

		return title_;

	}


	int getIsbn()  {

		return isbn_;

	}

	int getPrice()  {

		return price_;

	}


	void setAuthor(string author) {
		author_ = author;
	}


	


	// copy assignment operator which needs to be implemented, because we have implemented a move constructor 
	Book& operator = (Book const& rhs) {
		
		author_ = rhs.author_;
		 isbn_ = rhs.isbn_;
		price_ = rhs.price_;
		 title_ = rhs.title_;

		return *this;
	}


	// move assignment operator , cannot use const 

	//Book& operator = (Book const && rhs) => wrong , we are actually changing the value for rhs , so we cannot use const here
	Book& operator = (Book  && rhs) {

		author_ = std::move(rhs.author_);
		isbn_ = std::move(rhs.isbn_);
		price_ = std::move(rhs.price_);
		title_ = std::move(rhs.title_);

		return *this;
	}


	ostream& operator<<(ostream& os, Book&  dt)
	{
		os << dt.getAuthor() << '/' << dt.getIsbn() << '/' << dt.getPrice() << '/' << dt.getTitle() << endl;
		return os;
	}




};


Last edited on
The overloads of operator>> and operator<< that take a std::istream& or std::ostream& as the left hand argument are known as insertion and extraction operators. Since they take the user-defined type as the right argument (b in a@b), they must be implemented as non-members.
These operators are sometimes implemented as friend functions.
http://en.cppreference.com/w/cpp/language/operators


For instance, line 108:
1
2
// ostream& operator<<(ostream& os, Book&  dt)
friend std::ostream& operator<<( std::ostream& os, const Book&  bk )
what do u mean by argument (b in a@b) ?
b is the second operand of the binary operator @.

For example, in: std::cout << my_book, std::cout is a, << is @, and my_book is b
Last edited on
I don't get this sentence :

Since they take the user-defined type as the right argument (b in a@b), they must be implemented as non-members.

so why is that if I can overload an operator like the "+" sign as a member function , but not use the ostream operator as a member function which takes the same argument ?

Consider use of the overloaded operator in: std::cout << my_book

The type of the first operand std::cout (the operand on the left hand side) is a stream type defined by the standard library and the type of the second operand my_book (the operand on the right hand side) is our user defined type.

This overloaded operator, if implemented as a member function must be a member function of the stream type defined by the standard library (the type of the operand on the left hand side). Since we can't change the implementation of a standard-library-defined type, the only viable option is to overload the operator as a non member function.
Topic archived. No new replies allowed.