0
votes

I am making a fraction class for a school project, and my brain is frying. I was told to overload the << and >> operators through the friend keyword. But I'm getting errors for this.

I've posted the relevant code here: http://pastebin.com/NgCABGJ2

The errors include: error C2270: '<<' : modifiers not allowed on nonmember functions (this error is for all the ones that are declared as friends)

This was at the operator< definition. error C2333: 'Fraction::operator <' : error in function declaration; skipping function body

There's 46 in all... this is a nightmare.

EDIT:

Thanks, I solved almost all the errors, but there's still 3

error C2664: 'Fraction::Fraction(const Fraction &)' : cannot convert parameter 1 from 'int' to 'const Fraction &' Occurs at this statement:

Fraction<int> test1, test2, test3(10);

error C2248: 'Fraction::operator ==' : cannot access private member declared in class 'Fraction' error C2248: 'Fraction::operator <' : cannot access private member declared in class 'Fraction'

I don't understand these two, but it occurs at these statements:

    if (test1 == test2)
    cout << "\nTest1 is equal to Test2";
if (test1 < test2)
    cout << "\nTest1 is less than Test2";

Thanks!

<><><>>EDIT2<<><><>

I fixed the other private access errors, but now i have some reaaaaaaaally bizarre errors:

Full code: http://pastebin.com/MVrB67SR

Errors:

Error 1 error LNK2001: unresolved external symbol "class Fraction __cdecl operator-(class Fraction const &,class Fraction const &)" (??G@YA?AV?$Fraction@H@@ABV0@0@Z) Error 2 error LNK2001: unresolved external symbol "class Fraction __cdecl operator+(class Fraction const &,class Fraction const &)" (??H@YA?AV?$Fraction@H@@ABV0@0@Z) Error 3 error LNK2001: unresolved external symbol "class Fraction __cdecl operator/(class Fraction const &,class Fraction const &)" (??K@YA?AV?$Fraction@H@@ABV0@0@Z) c:\Users\caleb jares\documents\visual studio 2010\Projects\Solution11-5\Solution11-5\Solution11-5.obj Error 4 error LNK2001: unresolved external symbol "class Fraction __cdecl operator*(class Fraction const &,class Fraction const &)" (??D@YA?AV?$Fraction@H@@ABV0@0@Z) Error 5 error LNK2001: unresolved external symbol "class std::basic_ostream > & __cdecl operator<<(class std::basic_ostream > const &,class Fraction)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@ABV01@V?$Fraction@H@@@Z) Error 6 error LNK2001: unresolved external symbol "class std::basic_istream > & __cdecl operator>>(class std::basic_istream > const &,class Fraction)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@ABV01@V?$Fraction@H@@@Z) Error 7 error LNK1120: 6 unresolved externals

Again, thanks for help!

5
I sort of don't like that you put the code on pastebin, but at least the expiration on it is 'never' so the link should always remain valid. - Omnifarious
I didn't think it would be a good thing to flood this question. Should I always paste the code on here? - Caleb Jares
You can post a "reduced" code snippet, that is, representative code that causes the compiler errors. - In silico

5 Answers

1
votes

Just take the const off... they're not member functions, so they can't be const. You should pass the class object by reference too... no point making copies all the time.

1
votes

Sounds like you tried to declare friend ostream &operator<<(…) const; . The important thing about friends is that they are not members. A friend function exists outside the scope of the class, even if it is defined inside the class {} block. In other words, you are declaring a function ::operator<<(), not fraction::operator<<(). And only member functions can have that trailing const, since it modifies the type of this.

Fact is, operator<< for output usually shouldn't be a friend anyway. It just gets the value and forwards it to the stream… that shouldn't require any special permission! Same applies to operator<.

Take the functions outside the class block entirely. There's no way your TA can complain about your design using friend less often.

1
votes

I can't figure out the first of your new errors, but the operator== and operator< errors are because they're private inside your class by default. You need a public: line in front of them so they're accessible to the outside world.

0
votes

The modifiers it's referring is the const at the end of the function, after the parameters:

friend ostream& operator<<(const ostream& output, const Fraction<T> value) const; //<-- that
friend istream& operator>>(const istream& input, Fraction<T> value) const; // <-- and that

The const modifier indicates that the function doesn't modify the object that it belongs to. Since they aren't member functions, they don't belong to any object.

0
votes

The const keyword following the function declaration is only allowed for member functions:

// This is not a member function!
template <class T>
ostream& operator<<(const ostream& output,
                    const Fraction<T>& value) /* No const! */
{
    // ...
}

It's not allowed because a const at the end of a member function declaration means this member function will not modify non-mutable values of the *this object. Since this is a non-member function, a const applied to the end of the function declaration is an error.

Also, if you define the < operator (or other operators like >, +, -, etc.) as a member of the class, it can only accept a single parameter:

// Only accepts a single parameter (the "right-hand-side" argument)
bool operator<(Fraction<T> const& right) const
{
    // ...
}

Although as Potatoswatter has pointed out, you should define these kinds of operators outside the class as free functions.