Difference between overloading Insertion operator and plus operator - c++

Both >> and + operators are binary operators. What does the difference in their syntaxes mean?
Why does >> have a return type (return by reference)? I know it is stupid but I am really confused between their syntaxes and would love a brief explanation.
Sparse operator +(Sparse &s); //code for plus operator
friend istream & operator >>(istream &is,Sparse &s); //code for insertion operator

operator+ combines the data of two input objects (in your example, the left-hand object is *this) and returns a new object containing the combined data.
operator>> (and operator<<) returns a reference to the stream that is being acted on. This allows for chaining multiple stream operations, eg:
cin >> var1 >> var2 ...;
// which is the same as:
// cin.operator>>(var1).operator>>(var2) ...
// or:
// operator>>(operator>>(cin, var1), var2) ...
// etc, depending on the particular types and operator overloads being used
cout << var1 << var2 ...;
// which is the same as:
// cout.operator<<(var1).operator<<(var2) ...
// or:
// operator<<(operator<<(cout, var1), var2) ...
// etc, depending on the particular types and operator overloads being used
Without being able to chain, stream operations would have to be called individually instead, eg:
cin >> var1;
cin >> var2;
...
cout << var1;
cout << var2;
...

Related

c++ overloaded (stream extraction and insertion) operator function as member function? [duplicate]

This question already has answers here:
Can't Overload operator<< as member function
(3 answers)
Closed 8 months ago.
From c++ how to program 10th edition by deitel
//Fig. 10.3: PhoneNumber.h
//PhoneNumber class definition
#ifndef PHONENUMBER_H
#define PHONENUMBER_H
#include <iostream>
#include <string>
class PhoneNumber
{
friend std::ostream& operator<<(std::ostream&, const PhoneNumber&);
friend std::istream& operator>>(std::istream&, PhoneNumber&);
private:
std::string areaCode; //3-digit area code
std::string exchange; //3-digit exchange
std::string line; //4-digit line
};
#endif // PHONENUMBER_H
//Fig. 10.4: PhoneNumber.cpp
//Overloaded stream insertion and stream extraction operators
#include <iomanip>
#include "PhoneNumber.h"
using namespace std;
//overloaded stream insertion operator; cannot be a member function
//if we would like to invoke it with cout << somePhoneNumber;
ostream& operator<<(ostream& output, const PhoneNumber& number)
{
output << "Area code: " << number.areaCode << "\nExchange: "
<< number.exchange << "\nLine: " << number.line << "\n"
<< "(" << number.areaCode << ") " << number.exchange << "-"
<< number.line << "\n";
return output; //enables cout << a << b << c;
}
//overloaded stream extraction operator; cannot be a member function
//if we would like to invoke it with cin >> somePhoneNumber;
istream& operator>>(istream& input, PhoneNumber& number)
{
input.ignore(); //skip (
input >> setw(3) >> number.areaCode; //input area code
input.ignore(2); //skip ) and space
input >> setw(3) >> number.exchange; //input exchange
input.ignore(); //skip dash (-)
input >> setw(4) >> number.line; //input line
return input; //enables cin >> a >> b >> c
}
//Fig. 10.5: fig10_5.cpp
//Demonstrating Class PhoneNumber's overloaded stream insertion
//and stream extraction operators.
#include <iostream>
#include "PhoneNumber.h"
#include <string>
using namespace std;
int main()
{
PhoneNumber phone; //create object phone
cout << "Enter phone number in the form (555) 555-5555:" << endl;
//cin >> phone invokes operator>> by implicitly issuing
//the non-member function call operator>>(cin, phone)
cin >> phone;
//cout << phone invokes operator<< bby implicitly issuing
//the non-member function call operator<<(cout, phone)
cout << phone << endl;
}
I understand from the book that the overloaded operator function for binary operator can be member function only when the left operand is an object of the class in which the function is a member because the member function can only be accessed by left operand which is the object of the class.
however I don't understand this part
" The overloaded stream insertion operator (<<) is used in an expression in which the
left operand has type ostream&, as in cout << classObject. To use the operator in this
manner where the right operand is an object of a user-defined class, it must be overloaded
as a non-member function. To be a member function, operator << would have to be a
member of class ostream. This is not possible for user-defined classes, since we are not
allowed to modify C++ Standard Library classes. "
my question is
whether the stream extraction and insertion operator is part of the ostream and istream respectively?
what does the part highlighted in bold mean?
My guess is that we cannot add user defined function into the C++ Standard Library class but the part in bold makes me kind of confused. do we have to add the operator << as member of class ostream to make the overloaded operator function as member function of ostream?
I always thought that stream << and >> operator were part of ostream and istream respectively.
Correct me if I am wrong. thank you in advance.
No, not for regular user defined types. The functions you made into friends in your class definition are free functions:
std::ostream& operator<<(std::ostream&, const PhoneNumber&);
std::istream& operator>>(std::istream&, PhoneNumber&);
std::basic_ostream does have some operator<< member overloads for fundamental types, such as int, and some types defined in the standard library though. If you inherit from some of those standard types, like std::basic_streambuf<CharT, Traits>, you will be able to use the basic_ostream::operator<< member overloads for those types.
It means that you are not allowed to modify the definition of std::basic_ostream to add std::basic_ostream& operator<<(const PhoneNumber&) as a member function.
You might have already read about overloading. There is not one function called operator<<, there are multiple. Some of those are class members, others aren't. The compiler will choose the right operator<< based on the two arguments.
When the compiler looks for overloads of operator<<, it will check class methods of the object on the left-hand side only. (If that's even a class. In 1<<3==8 the arguments are ints). For that reason, when the compiler sees std::cout << YourClass{} it won't look for YourClass::operator<<(ostream&).
If you wrote YourClass{} << std::cout (VERY unusual), the compiler would look in YourClass. Rules are rules, and there is no hard rule that forbids that order. But it would break the usual chaining of std::cout << a << b << c, so it's very inconvenient. So to make the usual chaining work, we do it as your textbook tells you.

How does this right shifts work: stringstream >> unsigned int >> unsigned int?

Im working with the book SFML Game Development by Examples and I dont really get what this sentence does. I've never seen something like this
void Anim_Directional::ReadIn(std::stringstream& l_stream){
l_stream >> m_frameStart >> m_frameEnd >> m_frameRow
>> m_frameTime >> m_frameActionStart >> m_frameActionEnd;
}
In C++ they got the "bright" idea of overloading the rightshift and leftshift operators with streams to represent serialization/deserialization.
stream >> var
means "read var from stream".
Symmetrically
stream << var
mean "put var into stream"
The operation of "streaming" in or out also returns the stream, so you can chain operations like:
stream >> var1 >> var2;
Note that the "streaming" was chosen just because of the look and because the priority was considered reasonable, but it's still just an overloaded operator and implies for example no strict sequence of evaluation. For example in:
stream << f() << g();
may be function g is called (somewhat surprisingly) before function f.
NOTE: the sequencing problem was handled by hammering this special case in last C++ standard (C++17). While it doesn't hold in general it's guaranteed for shift operators (presumably for this specific reason). So in f()+g() may be f is called later than g, but in f()<<g() this cannot happen.
C++ allows you to overload >> and << operators. std::stringstream is a derivative of std::istream and it inherits the >> operator overloads of std::istream.
The std::istream has a bunch of overloads for many common types. You can find a list of them here.
A typical std::istream >> operator overload looks as follows:
std::istream& operator>>(std::istream& stream, YourType& var) {
/*
** code here to parse and read a 'YourType' into 'var'
*/
/* var is set */
return stream; /* return the same stream to allow chaining */
}
When you do some_stream >> YourType_object, the matching >> operator overload is invoked. In the aforementioned case, our operator overload is invoked with stream parameter taking some_stream and var taking YourType_object.
The >> overloads (and << overloads too) intelligently return the stream which they operated; thereby, allowing a series of >> operators to be chained.

Is the std::istream type EqualityComparable?

My question would have a boolean answer: yes or not. Whichever it would be, can someone explain how the following code is compiled by both GNU-g++ 4.9.2 and clang 3.5, while GNU-g++ 5.1.1 no longer accepts it, claiming that there is no matching operator==?
And how it could be changed, for this last compiler, in order to have the same results i.e. to have the operator>> able to distinguish, in such a simple way, whether
it is called by the standard input stream or by something else?
# include <iostream>
# include <fstream>
struct S {};
std::istream& operator >> (std::istream& i, S& s)
{
if(i == std::cin) std::clog << "this is standard input\n";
else std::clog << "this is some other input stream\n";
return i;
}
int main(int narg, const char ** args)
{
S s;
std :: cin >> s;
std::ifstream inp(args[1]);
inp >> s;
}
// to be executed with the name of an existing
// disk file on the command line....
No. There's no operator== that operates on std::istream objects.
Your being able to compare two std::istreams is an unfortunate consequence caused by the conversion function of std::istream, specifically operator void*. In the expression i == std::cin, both i and std::cin are implicitly converted to void*, and the resulting values are compared. This is not really meaningful. This conversion function was removed in C++11 (replaced by an explicit conversion function, which won't be called in this situation), so if you enable the C++11 mode, the code will not compile.
As is stated here, if you want to check whether the reference i refers to std::cin, you can use &i == &std::cin.
Standard C++ streams don't have ==, >, < operators because they are not very meaningful in that context: what should "stream a is > than stream b" mean?
However, it shouldn't matter what type of istream you're dealing with: as long as you're not using specific methods defined in descendant classes (like is_open), base methods are shared (extracting, for instance). Whether you're extracting a string from a istringstream or a ifstream, you just do in >> str and let polymorphism take action.
If you really want to know the polymorphic type of the istream, you can use typeid or, simply, function overloading. In your case, with RTTI(typeid)
if ( typeid(in) == typeid(std::cin) )
// cin
else
// another istream type
Using overloading:
std::istream& operator >> (std::istream& i, S& s)
{
std::clog << "this is standard input\n";
return i;
}
std::ifstream& operator>>(std::ifstream& i, S& s)
{
std::clog << "this is some file input stream\n";
return i;
}

no operator >> matches these operands

I've been trying to overload the >> operator. I have a class that has two private variables:
Class Complex
{
private:
double real;
double imaginary;
};
In addition I have a friend function that overloads the >> operator:
friend istream & operator>>(istream &is, Complex &c)
In the implementation of the function I've tried many ways to write into the variable of object c but I keep getting an error no operator >> matches these operands
I looked around and read that I need to write into a reference of the variable, so I tried the following:
istream & operator>>(istream &is, Complex &c)
{
using std::cout;
double &r = c.real;
cout << "real: " << is >> r;
return is;
}
However this still gives me the same error.
I'm slightly confused as I tried is >> c.real and didn't work.
On one of the answers in a similar SO question, someone suggested writing into a local variable and setting the object variable it, something like:
double d;
cin >> d;
setReal(d);
I'm trying to find a more simpler way to achieve this rather than using a method or setting the variable to a local one.
The solution could be a simple one, but I'm really just a beginner in C++, so please take it easy on me :P.
Test case:
using std::cin;
Complex c;
cin >> c;
Exact error message:
Error 1 error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::basic_ostream<_Elem,_Traits>' (or there is no acceptable conversion)
The error is on this line:
cout << "real: " << is >> r;
This is interpreted as
((cout << "real: ") << is) >> r
The problem here is that you can't have a line like this where you switch from outputting to cout and start reading from is. A better way to do this would be
cout << "real: ";
is >> r;
That said, this is a very bad idea. You should not have operator >> display a prompt, since it means that if you want to read in an object of your type from a file, every time you do so you will get the prompt "real" displayed on-screen. You should have operator >> just read the representation, and explicitly prompt before reading if that's what you want to do.
Hope this helps!
The error is on this line:
cout << "real: " << is >> r;
Did you mean to use << instead of >> on that last one? Since you used >>, it's trying to write "is" into cout, but there is no overload of operator<< that takes a basic_ostream and a basic_istream.

overloading cascading insertion operator

Here are the instructions verbatim:
String insertion/extraction operators (<< and >>) need to be overloaded within the MyString object. These operators will also need to be capable of cascaded operations (i.e., cout << String1 << String2 or cin >> String1 >> String2). The string insertion operator (>>) will read an entire line of characters that is either terminated by an end-of-line character (\n) or 256 characters long. An input line that exceeds 256 characters will be limited to only the first 256 characters.
With that, this is the code I've gotten thus far:
in my .cpp file:
istream& MyString::operator>>(istream& input, MyString& rhs)
{
char* temp;
int size(256);
temp = new char[size];
input.get(temp,size);
rhs = MyString(temp);
delete [] temp;
return input;
}
in my .h file:
istream& operator>>(istream& input, MyString& rhs);
call from main.cpp file:
MyString String1;
const MyString ConstString("Target string"); //Test of alternate constructor
MyString SearchString; //Test of default constructor that should set "Hello World"
MyString TargetString (String1); //Test of copy constructor
cout << "Please enter two strings. ";
cout << "Each string needs to be shorter than 256 characters or terminated by
/.\n" << endl;
cout << "The first string will be searched to see whether it contains exactly the second string. " << endl;
cin >> SearchString >> TargetString; // Test of cascaded string-extraction operator<<
The error that I get is: istream& MyString::operator>>(std::istream&, MyString&)รข must take exactly one argument
How can I correct this? I am super confused on how to do this without BOTH the rhs and input
You have to create the operator>> as a non-member function.
As it is now, your function expects three arguments: the implicit invoking object, the istream&, and the MyString& rhs. However, since operator>> is a binary operator (it takes exactly two arguments) this won't work.
The way to do this is to make it a non-member function:
// prototype, OUTSIDE the class definition
istream& operator>>(istream&, MyString&);
// implementation
istream& operator>>(istream& lhs, MyString& rhs) {
// logic
return lhs;
}
And doing it that way (non-member function) is the way you have to do all operators where you want your class to be on the right side, and a class that you can't modify on the left side.
Also note that if you want to have that function access private or protected members of your objects, you have to declare it friend in your class definition.