Operator overloading c++ >> istream - c++

I want to overload the operator >> so that when I use cin>> I will be allowed to set my object's attributes,the overloading of << is working but not >>, here is my code.`
#include <iostream>
#include <cstdlib>
using namespace std;
class fraction{
private:
int den;
int nom;
public:
fraction(){nom=0;den=1;}
fraction(int x,int y){nom=x;den=y;}
fraction(const fraction &);
~fraction();
friend ostream& operator<<(ostream &,const fraction &);
friend istream& operator>>(istream &,fraction &);
fraction operator*(const fraction &);
fraction operator/(const fraction &);
fraction operator+(const fraction &);
fraction operator-(const fraction &);
friend void simple(fraction &);
};
istream operator>>(istream& is,fraction &v){
is>>v.nom;
is>>v.den;
return is;
}
`
And here is the error:
main.cpp: In function ‘std::istream operator>>(std::istream&, fraction&)’:
main.cpp:10:7: error: ‘int fraction::nom’ is private
main.cpp:53:4: error: within this context
main.cpp:9:7: error: ‘int fraction::den’ is private
main.cpp:54:4: error: within this context
In file included from /usr/include/c++/4.7/ios:43:0,
from /usr/include/c++/4.7/ostream:40,
from /usr/include/c++/4.7/iostream:40,
from main.cpp:1:
/usr/include/c++/4.7/bits/ios_base.h: In copy constructor ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’:
/usr/include/c++/4.7/bits/ios_base.h:788:5: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
In file included from /usr/include/c++/4.7/ios:45:0,
from /usr/include/c++/4.7/ostream:40,
from /usr/include/c++/4.7/iostream:40,
from main.cpp:1:
/usr/include/c++/4.7/bits/basic_ios.h:64:11: error: within this context
In file included from /usr/include/c++/4.7/iostream:41:0,
from main.cpp:1:
/usr/include/c++/4.7/istream: In copy constructor ‘std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)’:
/usr/include/c++/4.7/istream:56:11: note: synthesized method ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’ first required here
main.cpp: In function ‘std::istream operator>>(std::istream&, fraction&)’:
main.cpp:55:9: note: synthesized method ‘std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)’ first required here
Can anyone tell me what's wrong ?

Declare the function header for the overloaded operator as follows:
istream &operator>>(istream& is,fraction &v){
The & was missing for the return value.

Related

SortedVector not calling functions properly?

The compiler is telling me that these functions do not belong to my class or vector. I'm a bit confused as to where I could have gone wrong. Any help would be appreciated as i scramble to figure this out. I put the header for vector but that does not resolve the issue. It seems as though my compiler is failing to detect my .h file and my private variable sorted_vector.
//Compiler
In file included from SortedVector.cpp:1:0:
SortedVector.h:22:3: error: ‘vector’ does not name a type
vector<int> sorted_vector;
^~~~~~
SortedVector.cpp: In constructor ‘SortedVector::SortedVector(int)’:
SortedVector.cpp:5:2: error: ‘sorted_vector’ was not declared in this scope
sorted_vector.reserve(cap);
^~~~~~~~~~~~~
SortedVector.cpp: In member function ‘int SortedVector::getCapacity() const’:
SortedVector.cpp:9:9: error: ‘sorted_vector’ was not declared in this scope
return sorted_vector.capacity();
^~~~~~~~~~~~~
SortedVector.cpp: In member function ‘int SortedVector::getSize() const’:
SortedVector.cpp:13:9: error: ‘sorted_vector’ was not declared in this scope
return sorted_vector.size();
^~~~~~~~~~~~~
SortedVector.cpp: In member function ‘bool SortedVector::isEmpty() const’:
SortedVector.cpp:17:6: error: ‘sorted_vector’ was not declared in this scope
if (sorted_vector.empty())
^~~~~~~~~~~~~
SortedVector.cpp: In member function ‘void SortedVector::insertVal(int)’:
SortedVector.cpp:25:8: error: ‘sorted_vector’ was not declared in this scope
if(sorted_vector.isEmpty())
^~~~~~~~~~~~~
SortedVector.cpp:28:8: error: ‘sorted_vector’ was not declared in this scope
if(sorted_vector.isEmpty()){
^~~~~~~~~~~~~
SortedVector.cpp: At global scope:
SortedVector.cpp:39:5: error: prototype for ‘int SortedVector::find(int)’ does not match any in class ‘SortedVector’
int SortedVector::find(int val) {
^~~~~~~~~~~~
In file included from SortedVector.cpp:1:0:
SortedVector.h:14:7: error: candidate is: int SortedVector::find(int) const
int find(int val) const;
^~~~
SortedVector.cpp: In member function ‘bool SortedVector::deleteVal(int)’:
SortedVector.cpp:50:2: error: ‘vector’ was not declared in this scope
vector<int> temp;
^~~~~~
SortedVector.cpp:50:2: note: suggested alternative:
In file included from /usr/include/c++/6/vector:64:0,
from SortedVector.h:6,
from SortedVector.cpp:1:
/usr/include/c++/6/bits/stl_vector.h:214:11: note: ‘std::vector’
class vector : protected _Vector_base<_Tp, _Alloc>
^~~~~~
SortedVector.cpp:50:9: error: expected primary-expression before ‘int’
vector<int> temp;
^~~
SortedVector.cpp:51:2: error: ‘temp’ was not declared in this scope
temp.reserve(sorted_vector.capacity());
^~~~
SortedVector.cpp:51:15: error: ‘sorted_vector’ was not declared in this scope
temp.reserve(sorted_vector.capacity());
^~~~~~~~~~~~~
SortedVector.cpp:75:1: error: expected ‘}’ at end of input
}
//SortedVector.h
#ifndef SORTEDVECTOR_H_
#define SORTEDVECTOR_H_
#include <iostream>
using std::ostream;
#include <vector>
class SortedVector {
public:
SortedVector();
SortedVector(int cap = 10);
void insertVal(int val);
int find(int val) const;
bool deleteVal(int val);
bool isEmpty() const;
friend ostream & operator<<(ostream & out, const SortedVector & sV);
int getCapacity() const;
int getSize() const;
private:
vector<int> sorted_vector;
};
#endif
//SortedVector.cpp
#include "SortedVector.h"
#include <vector>
SortedVector::SortedVector(int cap) {
sorted_vector.reserve(cap);
}
int SortedVector::getCapacity() const{
return sorted_vector.capacity();
}
int SortedVector::getSize() const{
return sorted_vector.size();
}
bool SortedVector::isEmpty() const{
if (sorted_vector.empty())
return true;
else
return false;
}
void SortedVector::insertVal(int val) {
if(sorted_vector.isEmpty())
sorted_vector.push_back(val);
if(sorted_vector.isEmpty()){
for(int i=0;i!=sorted_vector.size();i++){
if(sorted_vector[i]<=val)
sorted_vector.insertVal(val);
}
}
}
int SortedVector::find(int val) {
for(int i=0; i<sorted_vector.size(); i++){
if(sorted_vector[i]==val)
return i;
else
return -1;
}
}
bool SortedVector::deleteVal(int val) {
vector<int> temp;
temp.reserve(sorted_vector.capacity());
temp = sorted_vector;
int idx = sorted_vector.find(val)
if (idx!= -1 ){
for(int i =0; i<sorted_vector.size(); i++){
if(i==idx)
continue;
temp.push_back(sorted_vector[i]);
}
sorted_vector=temp;
return true
}
else
return false;
}
ostream & operator<<(ostream & out, const SortedVector & sV) {
for(int i = 0; i < sV.getSize(); i++) {
out << sV.sorted_vector[i] << " ";
}
return out;
}

Unable to overload stream extraction operator (>>) in C++

I'm currently trying to understand the basic concepts of operator overloading in C++. Therefore, I created a class wheel that is able to read from a stream by overloading the stream extraction operator >>.
wheel.h
#ifndef WHEEL_H
#define WHEEL_H
#include <cassert>
#include <ostream>
#include <string>
class wheel final {
float rimDiameter;
int productionYear;
std::string velocityIndex = "N/A";
std::string manufacturer = "N/A";
public:
wheel() = default;
wheel( float rimDiameter,
int productionYear,
std::string velocityIndex,
std::string manufacturer
) : rimDiameter{rimDiameter},
productionYear{productionYear},
velocityIndex{velocityIndex},
manufacturer{manufacturer}
{}
~wheel() = default;
friend
auto operator<<(std::ostream &os, const wheel &self) -> std::ostream &;
friend
auto operator>>(std::istream &is, wheel &self) -> std::istream &;
};
#endif
wheel.cpp
#include "wheel.h"
auto operator<<(std::ostream &os, const wheel &self) -> std::ostream & {
return os << " WHEEL" << std::endl
<< " =============================" << std::endl
<< " Rim Diameter: " << self.rimDiameter << "\"" << std::endl
<< " Year of Production: " << self.productionYear << std::endl
<< " Velocity Index: " << self.velocityIndex << std::endl
<< " Manufacutrer: " << self.manufacturer << std::endl;
}
auto operator>>(std::istream &is, wheel &self) -> std::istream & {
char c[3];
is >>
self.rimDiameter >> c[0] >>
self.productionYear >> c[1] >>
self.velocityIndex >> c[2] >>
self.manufacturer;
assert(c[0] == ';' && c[1] == ';' && c[2] == ';');
return is;
}
main.cpp
#include <iostream>
#include "wheel.h"
int main(void) {
wheel w;
std::cin >> w;
std::cout << w;
return 0;
}
To me, it all looks fine, but somehow I keep getting an error telling me that there is no match for 'operator>>' (operand types are 'std::istream {aka std::basic_istream<char>}' and 'float'):
$ make
g++-7 -g -std=c++17 -Wall -Wextra -Wconversion -Wpedantic -c main.cpp
g++-7 -g -std=c++17 -Wall -Wextra -Wconversion -Wpedantic -c wheel.cpp
wheel.cpp: In function 'std::istream& operator>>(std::istream&, wheel&)':
wheel.cpp:16:8: error: no match for 'operator>>' (operand types are 'std::istream {aka std::basic_istream<char>}' and 'float')
is >>
~~~^~
self.rimDiameter >> c[0] >>
~~~~~~~~~~~~~~~~
wheel.cpp:13:6: note: candidate: std::istream& operator>>(std::istream&, wheel&)
auto operator>>(std::istream &is, wheel &self) -> std::istream & {
^~~~~~~~
wheel.cpp:13:6: note: no known conversion for argument 2 from 'float' to 'wheel&'
In file included from /usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/string:53:0,
from /usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/bits/locale_classes.h:40,
from /usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/bits/ios_base.h:41,
from /usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/ios:42,
from /usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/ostream:38,
from wheel.h:5,
from wheel.cpp:1:
/usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/bits/basic_string.tcc:1465:5: note: candidate: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&)
operator>>(basic_istream<_CharT, _Traits>& __in,
^~~~~~~~
/usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/bits/basic_string.tcc:1465:5: note: template argument deduction/substitution failed:
wheel.cpp:17:14: note: mismatched types 'std::__cxx11::basic_string<_CharT, _Traits, _Alloc>' and 'float'
self.rimDiameter >> c[0] >>
^~~~~~~~~~~
make: *** [wheel.o] Error 1
What am I missing here?
You need to include iostream for input and output like this #include <iostream> and you'll avoid the error.
When outputting, it's the class over which the << operators are defined you always use ostream, but you forgot the case of inputting for >>.
#ifndef WHEEL_H
#define WHEEL_H
#include <cassert>
#include <iostream>
#include <string>
class wheel final {
float rimDiameter;
int productionYear;
std::string velocityIndex = "N/A";
std::string manufacturer = "N/A";
public:
wheel() = default;
wheel( float rimDiameter,
int productionYear,
std::string velocityIndex,
std::string manufacturer
) : rimDiameter{rimDiameter},
productionYear{productionYear},
velocityIndex{velocityIndex},
manufacturer{manufacturer}
{}
~wheel() = default;
friend
auto operator<<(std::ostream &os, const wheel &self) -> std::ostream &;
friend
auto operator >> (std::istream &is, wheel &self) -> std::istream &;
};
#endif /* wheel_hpp */
As #Ext3h pointed out, I am missing the respective include for istream.
Adding #include <istream> to wheel.h resolves the problem.
Thank you very much for you help, would have taken me forever to figure out the issue!

error: cannot bind ‘std::ostream in implementation file

First: I have tried reading and modifying my code based off no less than 7 other similar questions. At best, the other options trigger an avalanche of errors. With my current code, I'm down to a single error.
Putting it inside the class and using "friend" doesn't work, and using ostream& operator<< (ostream &out, const Fraction &rhs) makes a whole lot more errors.
The frustrating thing is that in c9.io this code works, but not on Netbeans.
In my main.cpp:
#include <iostream>
#include "fraction.h"
using namespace std;
int main() {
Fraction f(3, 4);
cout << f;
return 0;
}
In fraction.h:
#ifndef FRACTION_H
#define FRACTION_H
class Fraction{
public:
//constructor defs
//accessors
//modifiers/mutators
void setNumer(int newNum);
void setDenom(int newDenom);
void reduce();
private:
//instance variables
int numer;
int denom;
//helper functions
int gcd(int a, int b);
};
#endif /* FRACTION_H */
And in fraction.cpp:
#include "fraction.h"
#include <cmath>
#include <iostream>
using namespace std;
//code for constructors
//accessors
int Fraction::getNumer(){
return numer;
}
int Fraction::getDenom(){
return denom;
}
//modifiers/mutators
//other operator definitions
ostream& operator<< (ostream &out, Fraction &rhs){
if(rhs.getNumer() == 0){
out << 0;
} else if(rhs.getNumer() == rhs.getDenom()){
out << 1;
} else {
rhs.reduce();
out << rhs.getNumer() << "/" << rhs.getDenom();
}
}
The output is:
g++ -c -g -std=c++11 -MMD -MP -MF "build/Debug/GNU-Linux/main.o.d" -o build/Debug/GNU-Linux/main.o main.cpp
main.cpp: In function ‘int main()’:
main.cpp:6:13: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
cout << f;
^
In file included from /usr/include/c++/4.8/iostream:39:0,
from main.cpp:1:
/usr/include/c++/4.8/ostream:602:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Fraction]’
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
There is no knowledge of the operator<< function that is defined in Fraction.cpp in main.cpp Hence, the line
cout << f;
is a problem.
Add the declaration of the function in the .h file.
#ifndef FRACTION_H
#define FRACTION_H
#include <iostream>
class Fraction{
public:
//constructor defs
//accessors
//modifiers/mutators
void setNumer(int newNum);
void setDenom(int newDenom);
void reduce();
private:
//instance variables
int numer;
int denom;
//helper functions
int gcd(int a, int b);
};
std::ostream& operator<< (std::ostream &out, Fraction const& rhs);
// ^^^^ Using const&, not just Fraction&
#endif /* FRACTION
So the answer was partly what #r-sahu said:
I had to set getNumer() and getDenom() as const member functions BUT I could only get the errors to go away by NOT using const& in the function definition.
Good:
std::ostream& operator<< (std::ostream &out, Fraction rhs);
Not good:
std::ostream& operator<< (std::ostream &out, Fraction const& rhs);
It now compiles and runs. any insight on why making the member functions const but not passing the Fraction as const makes it work? I stumbled on this solution by accident and don't understand it.

Problems overloading the << Operator

I am trying to overload the << operator for my Currency class but I get this compiler error: C2143: syntax error : missing ';' before '&'
In my .h file I have:
friend ostream &operator << (ostream &, const Currency&);
And in my Currency.cpp file I have:
ostream &operator << (ostream &stream, const Currency &obj){
stream<<"$"<<obj.dollars<<"."<<obj.cents;
return stream;
}
Everything up until now worked fine, but choked once I put that in:
I have the following at the top of my .h file:
#ifndef CURRENCY_H
#define CURRENCY_H
#include<iostream>
#include<string>
#include<ostream>
#include<sstream>
class Currency; //forward delcaration
//Function prototypes for overloaded stream operators
ostream &operator << (ostream &, const Currency &);
I have no idea what I am doing wrong. Help would be great. Thanks
ostream is declared in namespace std and you are missing std:: identifier before it:
std::ostream &operator << (std::ostream &, const Currency &);
If you want to avoid std:: then after header file you can put using namespace statement:
...
#include<ostream>
using namespace std; // this is not desirable though in real world programming
ostream &operator << (ostream &, const Currency &);
Edit: using namespace <> is not recommended in real world programming at the file top. I have put that part just for FYI.

template class, friend operator << overload

I'm trying to overload the "<<" operator for a template class. I've the definition of the class in a .h file and its implementation in a .cpp file.
/tmp/ccjJIJhO.o: In function `main':
main.cpp:(.text+0xad): undefined reference to `std::basic_istream<char, std::char_traits<char> >& operator>><int>(std::basic_istream<char, std::char_traits<char> >&, FeatureVector<int>&)'
main.cpp:(.text+0xba): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& operator<< <int>(std::basic_ostream<char, std::char_traits<char> >&, FeatureVector<int> const&)'
collect2: ld returned 1 exit status
The class definition:
common.h
#include <iostream>
using namespace std;
featurevector.h
#ifndef FEATURE_VECTOR_H
#define FEATURE_VECTOR_H
#include <common.h>
template < class FEAT_TYPE >
class FeatureVector;
template < class FEAT_TYPE >
istream & operator >> (istream &, FeatureVector<FEAT_TYPE> &);
template < class FEAT_TYPE >
ostream & operator << (ostream &, const FeatureVector<FEAT_TYPE> &);
template < class FEAT_TYPE >
class FeatureVector{
public:
FeatureVector(int = 0);
...
friend istream & operator >> <>(istream &, FeatureVector<FEAT_TYPE> & );
friend ostream & operator << <>(ostream &, const FeatureVector<FEAT_TYPE> &);
...
~FeatureVector();
private:
int m_nDim;
FEAT_TYPE * m_pFeat;
};
#endif
featurevector.cpp
#include <featurevector.h>
...
template < class FEAT_TYPE >
istream & operator >> (istream & input, FeatureVector< FEAT_TYPE> & refFeat ){
int d;
for(d=0; d < refFeat.getDim(); d++){
input >> refFeat.m_pFeat[d];
}
return (input);
}
template < class FEAT_TYPE >
ostream & operator << (ostream & output, const FeatureVector< FEAT_TYPE > & refFeat ){
int d;
for(d=0; d < refFeat.getDim(); d++){
output << refFeat.m_pFeat[d] << " ";
}
output << endl;
return (output);
}
...
#include "featurevector-impl.cpp"
featurevector-impl.cpp
template class FeatureVector<int>;
//template istream & operator >> <>(istream &, FeatureVector<int> &);
//template ostream & operator << <>(ostream &, const FeatureVector<int> &);
mylib.h
#ifndef MY_LIB_H
#define MY_LIB_H
#include <featurevector.h>
#endif
main.cpp
#include <mylib.h>
#include <common.h>
int main(){
FeatureVector<int> pFeat(10);
cin >> (pFeat);
cout << (pFeat);
return (0);
}
Makefile associated with "mylib"
INC=./inc
SRC=./src
LIB=./lib
OBJ=./obj
CC=g++
CFLAGS=-O3 -Wall
mylib: $(LIB)/mylib.a
echo "mylib was created!..."
$(LIB)/mylib.a: \
$(OBJ)/featurevector.o
ar csr $(LIB)/mylib.a \
$(OBJ)/featurevector.o
$(OBJ)/featurevector.o: $(SRC)/featurevector.cpp
$(CC) -c $(CFLAGS) $(SRC)/featurevector.cpp -I$(INC) \
-o $(OBJ)/featurevector.o
clean:
rm -rf $(LIB)/*.a
rm -rf $(OBJ)/*.o
Makefile for main.cpp (the main.cpp with its Makefile are under an "app" directory)
LIB=../lib
INC=../inc
OBJ=../obj
BIN=../bin
CC=g++
CFLAGS=-O3 -Wall
LFLAGS=-lmylib -lm
$#.cpp: $(LIB)/mylib.a $#.cpp
cd ..; make; cd app;
$(CC) $(CFLAGS) $#.cpp -o $(BIN)/$# -I$(INC) -L$(LIB) $(LFLAGS)
clean:
rm -rf $(BIN)/*
According to this, you have to make the function known as template in your class definition.
class.h
#include <iostream>
using std::ostream;
template <typename T>
class A {
public:
...
template <typename J> // <-- CAUTION!
friend ostream &operator<<(ostream &output, const A<J> &a);
};
class.cpp
#include "class.h"
...
template <typename T>
ostream &operator<<(ostream &output, const A<T> &a) {
// Your implementation
return output;
}
...
template ostream &operator<<(ostream &output, const A<int> &a);
template ostream &operator<<(ostream &output, const A<float> &a);
If the line template <typename J> is removed, the compilation error "underfined reference" comes.
See FAQ item 35.12 Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?.
Your posted error code says that it is operator>> that is throwing an unresolved external error, not operator<<. In addition, your code won't compile because there is no convert constructor on myClass taking an int. So you have not posted the correct code.
But this works:
#include <iostream>
using namespace std;
template < class T >
class myClass;
template < class T >
ostream & operator << (ostream &, const myClass<T> &);
template < class T >
class myClass{
public:
myClass(int) {}
friend ostream & operator << <>(ostream &, const myClass<T> &);
private:
T m_Data;
};
template < class T >
ostream & operator << (ostream & out, const myClass<T> & refClass){
out << refClass.m_Data << endl;
return (out);
}
myClass<int>;
myClass<float>;
int main(int argc, char **argv){
myClass<int> test(5);
cout << test;
return 0;
}
Don't make it so complicated:
template<class FEAT_TYPE>
struct FeatureVector {
FeatureVector(int = 0);
friend std::istream& operator>>(std::istream &s, FeatureVector &x) {
for(int d = 0; d < x.getDim(); d++) {
s >> x.m_pFeat[d];
}
return s;
}
friend std::ostream& operator<<(std::ostream &s, FeatureVector const &x) {
// since you're terminating with " " rather than separating:
copy(x.m_pFeat, x.m_pFeat + x.getDim(), ostream_iterator<FEAT_TYPE>(s, " "));
s << endl;
return s;
}
//...
featurevector-impl.cpp is incorrect. Explicit template instantiations look like this:
template class FeatureVector<int>;
Since the operators aren't members, they must also be explicitly instantiated:
template istream & operator >> <>(istream &, FeatureVector<int> &);
I don't recommend splitting up your template definitions like this, though, unless you're really keen on micromanaging which specific classes will work with your template (which kind of goes against the spirit of using a template).