views:

52

answers:

2

I have a class called fraction, and I'm declaring some operators as friends. I declared the friend operators beforehand, as http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16 told me to do, but it only fixed +, -, *, and /. << and >> still don't work.

template <class T> class Fraction;
template <class T> Fraction<T> operator+ (Fraction<T> const& left, Fraction<T> const& right);
template <class T> Fraction<T> operator- (Fraction<T> const& left, Fraction<T> const& right);
template <class T> Fraction<T> operator* (Fraction<T> const& left, Fraction<T> const& right);
template <class T> Fraction<T> operator/ (Fraction<T> const& left, Fraction<T> const& right);
template <class T> ostream& operator<< (const ostream& output, Fraction<T> const& value);
template <class T> istream& operator>> (const ostream& input, Fraction<T> const& value);

And the class:

template <class T>
class Fraction
{
 ...

 friend Fraction<T> operator+ <>(const Fraction<T>& left, const Fraction<T>& right);
 friend Fraction<T> operator- <>(const Fraction<T>& left, const Fraction<T>& right);
 friend Fraction<T> operator* <>(const Fraction<T>& left, const Fraction<T>& right);
 friend Fraction<T> operator/ <>(const Fraction<T>& left, const Fraction<T>& right);

 friend ostream& operator<< <>(const ostream& output, const Fraction<T> value);
 friend istream& operator>> <>(const istream& input, Fraction<T> value);
}

template <class T> ostream& operator<< <>(const ostream& output, const Fraction<T>& value)
{
 output << value.Numerator << '/' << value.Denominator;

 return output;
}
template <class T> istream& operator>> <>(const istream& input, Fraction<T>& value)
{
 T n, d, char seperator;

 cin >> n >> seperator >> d;

 value.SetNumerator(n);
 value.SetDenominator(d);

 return input;
}
+2  A: 

Replace

template <class T> istream& operator>> <>(const istream& input, Fraction<T>& value)  { ...

with

template <class T> istream& operator>> (const istream& input, Fraction<T>& value)  { ...

And analogically for the other operator. The problem is that this way you are creating a blank template specialization which yields a different symbol than the one being forward-declared as friend.

EDIT:

Another problem I see is this forward declaration:

template <class T> istream& operator>> (const ostream& input, Fraction<T> const& value);

You declare its first parameter as const ostream&, it should be const istream&. This definitely will cause a linker error.

Side note: The original answer should not fix the errors according to the FAQ. However, I'd give it a shot if the problem persisted.

dark_charlie
It isn't working. Here's a link to the full code: http://pastebin.com/spam.php?i=yRBrYMtv Hope you can help!
cable729
Sorry, that link didn't work. Here's the right one: http://pastebin.com/Taf2E9hR
cable729
+5  A: 

As "dark_charlie" says, but remove the const.

I'd rather have made this as just a comment, but unfortunately StackOverflow does not yet allow me to comment (to the person feeling the urge to comment that I shouldn't make this comment: it's aimed at you).

Alf P. Steinbach
+1 for complaining so much. hope others upvote you so you can stop complaining ;)
slashmais
Ah, well, I answered a "bounty" question just for that. Hopefully (but the question was so vague I don't know if my answer covered it) it'll get me over the required the 50 points. I find this particular aspect of StackOverflow is utterly baffling, but perhaps it adds some game-like dimension -- earning points? Or perhaps it's an anti-spam device? Anyway, thanks! :-)
Alf P. Steinbach