Here is the Rational class that i’ve been working on:
rational.h
#include<iostream>
using namespace std;
#ifndef RATIONAL_H
#define RATIONAL_H
class Rational
{
int numerator,denominator;
public:
// the various constructors
Rational();
Rational(int);
Rational(int,int);
//member functions
int get_numerator()const{return numerator;}
int get_denominator()const{return denominator;}
// overloaded operators
// relational operators
bool operator==(const Rational&)const;
bool operator<(const Rational&)const;
bool operator<=(const Rational&)const;
bool operator>(const Rational&)const;
bool operator>=(const Rational&)const;
//arithmetic operators
Rational operator+(const Rational&);
Rational operator-(const Rational&);
Rational operator*(const Rational&);
Rational operator/(const Rational&);
//output operator
friend ostream& operator<<(ostream&, const Rational&);
};
#endif //RATIONAL_H
rational.cpp
#include "rational.h"
// implementation ofthe various constructors
Rational::Rational()
:numerator(0),denominator(1){}
Rational::Rational(int number)
:numerator(number),denominator(1){}
Rational::Rational(int n,int d)
:numerator(n),denominator(d)
{
if(denominator == 0) denominator = 1;
if(denominator < 0)
{
numerator *= -1;
denominator *= -1;
}
}
// implementation of overloaded operators
bool Rational::operator==(const Rational& rhs)const
{
if( numerator * rhs.get_denominator() == denominator * rhs.get_numerator() )
{
return true;
}
else return false;
}
bool Rational::operator<(const Rational& rhs)const
{
if( numerator * rhs.get_denominator() < denominator * rhs.get_numerator() )
{
return true;
}
else return false;
}
bool Rational::operator<=(const Rational& rhs)const
{
return operator==(rhs) || operator<(rhs);
}
bool Rational::operator>(const Rational& rhs)const
{
return !operator<(rhs);
}
bool Rational::operator>=(const Rational& rhs)const
{
return operator==(rhs) || operator>(rhs);
}
//arithmetic operators
Rational Rational::operator+(const Rational& rhs)
{
return Rational( (numerator * rhs.get_denominator() + denominator*rhs.get_numerator()), (denominator * rhs.get_denominator()) );
}
Rational Rational::operator-(const Rational& rhs)
{
//reuse of the + operator for substraction
return operator+(Rational(-1*rhs.get_numerator(),rhs.get_denominator()));
}
Rational Rational::operator*(const Rational& rhs)
{
return Rational(numerator * rhs.get_numerator(), denominator * rhs.get_denominator());
}
Rational Rational::operator/(const Rational& rhs)
{
//reuse of the * operator as division is the inverse of multiplication
return operator*(Rational(rhs.get_denominator(),rhs.get_numerator()));
}
// friend output operator
ostream& operator<<(ostream& os, const Rational& r)
{
os<<r.get_numerator()<<"/"<<r.get_denominator();
return os;
}
and the driver for the program driver.cpp
#include "rational.h"
int main()
{
Rational r1(),r2(3),r3(11,3),tmp;
cout<<r1+r2<<endl;
cout<<r2<<endl;
cout<<r2-r3<<endl;
cout<<r2*r3<<endl;
cout<<r1/r3;
return 0;
}
Here’s the error that i get when trying to compile it.
driver.cpp: In function ‘int main()’:
driver.cpp:6:12: error: no match for ‘operator+’ in ‘r1 + r2’
driver.cpp:6:12: note: candidates are:
/usr/include/c++/4.6/bits/stl_iterator.h:327:5: note: template<class _Iterator> std::reverse_iterator<_Iterator> std::operator+(typename std::reverse_iterator<_Iterator>::difference_type, const std::reverse_iterator<_Iterator>&)
/usr/include/c++/4.6/bits/basic_string.h:2306:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_string<_CharT, _Traits, _Alloc> std::operator+(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.tcc:694:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_string<_CharT, _Traits, _Alloc> std::operator+(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.tcc:710:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_string<_CharT, _Traits, _Alloc> std::operator+(_CharT, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.h:2343:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_string<_CharT, _Traits, _Alloc> std::operator+(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
/usr/include/c++/4.6/bits/basic_string.h:2359:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_string<_CharT, _Traits, _Alloc> std::operator+(const std::basic_string<_CharT, _Traits, _Alloc>&, _CharT)
driver.cpp:10:12: error: no match for ‘operator/’ in ‘r1 / r3’
When I comment the lines where I use the operator+ and operator/, then the code works.
This baffles me as I have implemented the operator- using operator+ and similarly the operator/ using operator*.
So if one of them works, I’d figure that the other would work too.
Can someone please explain what I have done wrong here?
Edit
I get even more errors when I use the operator==
rational.cpp:22:6: error: prototype for ‘bool Rational::operator==(const Rational&)’ does not match any in class ‘Rational’
rational.h:23:8: error: candidate is: bool Rational::operator==(Rational)
rational.cpp:31:6: error: prototype for ‘bool Rational::operator<(const Rational&) const’ does not match any in class ‘Rational’
rational.h:24:8: error: candidate is: bool Rational::operator<(Rational)
driver.cpp: In function ‘int main()’:
driver.cpp:11:10: error: no match for ‘operator==’ in ‘r1 == tmp’
driver.cpp:11:10: note: candidates are:
/usr/include/c++/4.6/bits/postypes.h:218:5: note: template<class _StateT> bool std::operator==(const std::fpos<_StateT>&, const std::fpos<_StateT>&)
/usr/include/c++/4.6/bits/stl_pair.h:201:5: note: template<class _T1, class _T2> bool std::operator==(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
/usr/include/c++/4.6/bits/stl_iterator.h:285:5: note: template<class _Iterator> bool std::operator==(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
/usr/include/c++/4.6/bits/stl_iterator.h:335:5: note: template<class _IteratorL, class _IteratorR> bool std::operator==(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)
/usr/include/c++/4.6/bits/allocator.h:122:5: note: template<class _T1, class _T2> bool std::operator==(const std::allocator<_T1>&, const std::allocator<_T2>&)
/usr/include/c++/4.6/bits/allocator.h:127:5: note: template<class _Tp> bool std::operator==(const std::allocator<_Tp1>&, const std::allocator<_Tp1>&)
/usr/include/c++/4.6/bits/basic_string.h:2427:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.h:2434:5: note: template<class _CharT> typename __gnu_cxx::__enable_if<std::__is_char<_Tp>::__value, bool>::__type std::operator==(const std::basic_string<_CharT>&, const std::basic_string<_CharT>&)
/usr/include/c++/4.6/bits/basic_string.h:2448:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.h:2460:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
/usr/include/c++/4.6/bits/streambuf_iterator.h:194:5: note: template<class _CharT, class _Traits> bool std::operator==(const std::istreambuf_iterator<_CharT, _Traits>&, const std::istreambuf_iterator<_CharT, _Traits>&)
What do these cryptic messages mean?
- Forum
- Beginners
- no match for operator>>
no match for operator>>
Hi, so I’m a total beginner and am having trouble trying to overload the insertion operator. When I try it tells me «error: no match for ‘operator>>’ (operand types are ‘std::istream’ {aka ‘std::basic_istream’} and ‘int’)»
Here is the header:
|
|
And this is the implementation file:
|
|
I assume that I have a type mismatch, but I guess I’m a little thick, because I don’t see it.
What do YOU think line 11 is doing in the 2nd one?
How big do you think that A array is?
you cannot cin an array. you have to loop and read one by one.
and C style arrays need a fixed size at compile time; the only way around this is a pointer of some sort (whether done for you or not).
edit, misread what you did, the >> is fine apart from trying to read and write an array.
Last edited on
There are three main issues with your code.
The first issue is that your array a is not specified as having any size. The size of arrays, whether in a class or not, must be known at compile time.
The second issue is second snippet, line 9: myArray::istream& is not a type. You meant to just write istream&.
The third issue is second snippet, line 11: You are calling >> on an array (a). Presumably you meant to call something more like:
|
|
You should also be thinking about bounds checking, e.g. (if arrayLen == maxSize) { don’t add to array }. This is assuming you have some notion of «MaxSize» (see first issue).
|
|
Last edited on
So does that mean that I could do this:
|
|
|
|
Wait, no, that still doesn’t work… Okay, I still seem to be misunderstanding something.
What does «not work» mean?
The same error comes up about «no match for ‘operator>>’ (operand types are ‘std::istream’ {aka ‘std::basic_istream’} and ‘int’)»
Perhaps something like:
|
|
person5273, your code that you have shown does not have problems, assuming it’s being successfully compiled/linked by however you are building it. I was able to copy and paste it into cpp.sh as one file and compile it (after removing the #include «myArray.h»), after adding a main function. So the problem exists in part of the code you are not showing.
The array size is specified at compile time.
Topic archived. No new replies allowed.
-
05-13-2008
#1

Registered User
No Match For Operator+ ???????
My Class:
Code:
#include <iostream> #include <string> using namespace std; class Integer { public: Integer(int i); Integer(std::string str); int getValue(); void setValue(int i); void add(Integer& i); void subtract(Integer& i); void multiply(Integer& i); void divide(Integer& i); private: int myInteger; };My Implementation:
Code:
#include <iostream> #include <string> #include "integer.h" Integer::Integer(int i) { myInteger = i; } Integer::Integer(std::string str) { myInteger = atoi( str.c_str() ); } int Integer::getValue() { return myInteger; } void Integer::setValue(int i) { myInteger = i; } void Integer::add(Integer& i) { myInteger = myInteger + i; } void Integer::subtract(Integer& i) { myInteger = myInteger - i; } void Integer::multiply(Integer& i) { myInteger = myInteger * i; } void Integer::divide(Integer& i) { myInteger = myInteger / i; }Errors:
Code:
integer.cpp: In member function �void Integer::add(Integer&)�: integer.cpp:31: error: no match for �operator+� in �((Integer*)this)->Integer::myInteger + i� integer.cpp: In member function �void Integer::subtract(Integer&)�: integer.cpp:36: error: no match for �operator-� in �((Integer*)this)->Integer::myInteger - i� integer.cpp: In member function �void Integer::multiply(Integer&)�: integer.cpp:41: error: no match for �operator*� in �((Integer*)this)->Integer::myInteger * i� integer.cpp: In member function �void Integer::divide(Integer&)�: integer.cpp:46: error: no match for �operator/� in �((Integer*)this)->Integer::myInteger / i� make: *** [integer.o] Error 1Why is this happening??? Why can’t I freaking *ADD*?????
Last edited by Paul22000; 05-14-2008 at 12:12 AM.
-
05-14-2008
#2

C++ Witch
Instead of:
Code:
myInteger = myInteger + i;
you probably intend to write:
Code:
myInteger = myInteger + i.myInteger;
or better yet:
Code:
myInteger += i.myInteger;
By the way, remove that using directive from your header. If you want to use it, use it in your source file instead. Also, for all the functions i should be a const Integer& since you do not modify it.
Originally Posted by Bjarne Stroustrup (2000-10-14)I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. «Finding the smallest program that demonstrates the error» is a powerful debugging tool.
Look up a C++ Reference and learn How To Ask Questions The Smart Way
-
05-14-2008
#3

Registered User
Originally Posted by laserlight
Instead of:
Code:
myInteger = myInteger + i;
you probably intend to write:
Code:
myInteger = myInteger + i.myInteger;
or better yet:
Code:
myInteger += i.myInteger;
By the way, remove that using directive from your header. If you want to use it, use it in your source file instead. Also, for all the functions i should be a const Integer& since you do not modify it.
THANKS!!!
-
05-14-2008
#4

C++まいる!Cをこわせ!
You can’t add an object (your class) because the compiler has no idea on how to do it. You can do it if you tell the compiler how to do it. It’s called operator overloading. You’ll probably get to it eventually.
Originally Posted by Adak
io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
Originally Posted by Salem
You mean it’s included as a crutch to help ancient programmers limp along without them having to relearn too much.
Outside of your DOS world, your header file is meaningless.
-
05-14-2008
#5

Registered User
Why are you creating functions like add, subtract, multiply, divide, etc. when you can just overload the operators? This is C++, not Java.
-
05-14-2008
#6

Registered User
Well, let’s give him a hint! A very straightforward way, you will find this in basic text books, is to overload operators as class member functions:
Code:
#include <iostream> #include <string> class Integer { public: Integer(int i); Integer(std::string str); int getValue(); void setValue(int i); Integer& operator+( Integer const& arg); // why use 'Integer' AND 'int' private: int myValue; }; // *** Integer& Integer :: operator+( Integer const& arg) { this->myValue += arg.myValue; return *this; }However, try to minimize your class with functions that concern your (private) attributes in the most direct way only, e.g., the constructors (default, copy, cast, ..) ‘setValue’, ‘getValue’. All other functions are best no-member, no-friend.
Why? Try to overload the operator+ for a class Double:
Code:
#include <iostream> #include <string> class Double { public: Double(double i); Double(std::string str); double getValue(); void setValue(double i); Double& operator+( Double const& arg); // suppose you have defined a class 'Double' Double& operator+( Integer const& arg); // to add your Integer to your Double private: double myValue; }; // *** Integer& Integer :: operator+( Integer const& arg) { this->myValue += arg.myValue; return *this; } Double& Double:: operator+( Integer const& arg) { this->myValue+= arg.myValue; return *this; }This will work for ‘ double + int’ , but it won’t for ‘ int + double ‘ . Why? In the member-operator, ‘*this’, so the double, is the left (implicit) argument of ‘+’, and ‘int’ the right argument. You cannot invert these.
Now you can say: «Ok, but I simply write an ‘operator+( Double)’ in my class ‘Integer’ «. Wrong: you cannot declare this before the class ‘Double’ has been declared!An even stronger argument: if you want to add an object of a class your colleague wrote, to your Integer, you cannot modify his/her class. And you do want this operator to be commutative.
There are better arguments, but let’s hold for now.
I would try it like this:
Code:
#include <iostream> #include <string> class Integer { public: Integer(); // no default constructor? Integer(int i); Integer(std::string str); int getValue(); void setValue(int i); Integer& operator+( Integer const& arg); // why use 'Integer' AND 'int' ?! private: int myValue; }; class Double { public: Double(); // don't you want a default constructor? Double(double i); // not explicit to cast implicitely Double to Integer Double(std::string str); double getValue(); void setValue(double i); private: double myValue; }; // *** Integer& operator+( Integer const& arg1, Integer const& arg2) { Integer result = arg1.myValue + arg2.myValue; return result; } Double& operator+( Integer const& arg1, Double const& arg2) { Double result = arg1.myValue + arg2.myValue; return result; } Double& operator+( Double const& arg1, Integer const& arg2) { Double result = arg1.myValue+ arg2.myValue; return result; } Double& operator+( Double const& arg1, Double const& arg2) { Double result = arg1.myValue + arg2.myValue; return result; }Ok, only the operator with the two ‘Double’ arguments would have sufficed, since implicit casts are allowed (no ‘explicit’ keyword in the one-argument constructor). But to make the point…
And any ‘operator@’ should be defined, if possible, in the canonical way by calling the member ‘operator@=’ (this _must_ be a member, like ‘=’).
EDIT: try to be as general as possible. Your class is called ‘Integer’, so why call the private attribute ‘myInteger’ ? Let’s call it ‘myValue’.
EDIT2: is #include <iostream> really always necessary?
Last edited by MarkZWEERS; 05-14-2008 at 06:49 AM.
-
05-14-2008
#7

Registered User
No there is no point in including iostream unless you are using the standard io streams (in, cout, clog, cerr, and their wide character equivalents).
It is too clear and so it is hard to see.
A dunce once searched for fire with a lighted lantern.
Had he known what fire was,
He could have cooked his rice much sooner.
-
05-14-2008
#8

Registered User
Guess that is what the good old teacher always told us huh 😉
-
05-14-2008
#9

C++ Witch
In this case I would #include <iosfwd> then overload of operators>> and << for I/O streams. In the implementation file, I would #include <istream> and <ostream>.
Originally Posted by Bjarne Stroustrup (2000-10-14)I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. «Finding the smallest program that demonstrates the error» is a powerful debugging tool.
Look up a C++ Reference and learn How To Ask Questions The Smart Way
-
05-14-2008
#10

The larch
MarkZWEERS, may I point out that you seem to be confusing operators + and += (where + is implemented using += and returning *this)?
It seems that after you do c = a + b in some examples, b would be unmodified, but both a and c would contain the sum.
In the rest of the cases you are returning references to local objects. (Operator + should return a copy of the result.)
I might be wrong.
Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
Quoted more than 1000 times (I hope).
-
05-14-2008
#11

Registered User
Oooops… copy-paste mistake.. sorry, here’s a correction:
Code:
#include <iostream> #include <string> class Integer { public: Integer(); // no default constructor? Integer(int i); Integer(std::string str); int getValue(); void setValue(int i); private: int myValue; }; class Double { public: Double(); // don't you want a default constructor? Double(double i); // not explicit to cast implicitely Double to Integer Double(std::string str); double getValue(); void setValue(double i); private: double myValue; }; // *** Integer operator+( Integer const& arg1, Integer const& arg2) { Integer result = arg1.myValue + arg2.myValue; return result; } Double operator+( Integer const& arg1, Double const& arg2) { Double result = arg1.myValue + arg2.myValue; return result; } Double operator+( Double const& arg1, Integer const& arg2) { Double result = arg1.myValue+ arg2.myValue; return result; } Double operator+( Double const& arg1, Double const& arg2) { Double result = arg1.myValue + arg2.myValue; return result; }
-
05-14-2008
#12

C++ Witch
MarkZWEERS, your code has a serious problem: operator+(const Integer&, const Integer&) is a non-member non-friend function, yet it directly accesses a private member variable of the Integer class.
Also, getValue() should be const, and perhaps it would be better to provide a non-explicit Double constructor that takes an Integer instead of having specific overloads to handle addition of a Double and an Integer. Oh, and std::string objects should be passed by (const) reference.
Originally Posted by Bjarne Stroustrup (2000-10-14)I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. «Finding the smallest program that demonstrates the error» is a powerful debugging tool.
Look up a C++ Reference and learn How To Ask Questions The Smart Way
-
05-14-2008
#13

C++まいる!Cをこわせ!
Any object should be preferred to be passed by a constant reference… That would make it possible for implicit conversions using the object’s constructors.
Though I don’t know if C++0x makes it legal for a non-const reference that can do the same?
Originally Posted by Adak
io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
Originally Posted by Salem
You mean it’s included as a crutch to help ancient programmers limp along without them having to relearn too much.
Outside of your DOS world, your header file is meaningless.
-
05-14-2008
#14

Registered User
yet it directly accesses a private member variable of the Integer class
yes, I would make getValue() ‘inline’ and then call this function instead of erroneously accessing the private attribute.
Didn’t touch the other things, so no credits for that…
Sorry for these stupid copy-paste errors, it’s not very rigorous.
it would be better to provide a non-explicit Double constructor to handle addition of a Double and an Integer
This is what I tried to point out in my first post…
-
05-14-2008
#15

Registered User
>> Oh, and std::string objects should be passed by (const) reference.
While I agree that this is generally a good idea, I don’t see much problem using string as a value type in instances where performance should not be a problem. I doubt a string that holds a double or integer will be very big and expensive to copy anyway.