Overloading conversion operator

Hi,

I want my class to be converted to a float number. So I have this as a method:
ClassName::operator float();

But it gives an error now:
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2738: 'operator float' : is ambiguous

What happened? If I remember correctly, there shouldn't be a return type to overload a conversion operator?
http://msdn.microsoft.com/en-us/library/ms173696.aspx

I think there is something wrong in your declarations?
Well, I have this:

1
2
3
4
5
6
7
8
9
class Fraction
{
public:
Fraction::operator float();

private:
float numerator;
float denominator;
};


and

1
2
3
4
Fraction::operator float()
{
	return numerator / denominator;
}


But I get the errors I already mentioned.
Last edited on
Remove Fraction:: when inside the class body
Wow, that's almost exactly what I thought of when I tested your code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
using namespace std;

struct fraction_t
  {
  int numerator;
  int denominator;

  fraction_t( int n = 0, int d = 1 ):
    numerator( n ),
    denominator( d )
    { }

  operator float() const
    {
    return float( numerator ) / float( denominator );
    }

  friend ostream& operator << ( ostream& outs, const fraction_t& frac );
  };

ostream& operator << ( ostream& outs, const fraction_t& frac )
  {
  int n = frac.numerator;
  int d = frac.denominator;
  if (d < 0)
    {
    n = -n;
    d = -d;
    }
  return outs << n << "/" << d;
  }

int main()
  {
  fraction_t f( 2, -5 );
  float v = f;

  cout << f << " = " << v << endl;

  return 0;
  }

One thing to note is that the operator float() is (should be) const -- it has no business modifying the object.

Hope this helps.
Thank you, it seems to work now!

I have made that mistake with all my other overloads, but none of them gave an error.
Last edited on
Now I get another error when trying to overload << and >>

error C2653: 'std' : is not a class or namespace name
And a lot of others after this.

1
2
3
4
5
class Fraction
{
public:
friend std::istream& operator>>(std::istream& is, Fraction& f);
friend std::ostream& operator<<(std::ostream& os, const Fraction& f);



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using namespace std;

istream& operator>>(istream& is, Fraction& f)
{
	cout << "Enter the numerator: ";
	cin >> f.numerator;
	cout << "Enter the denominator: ";
	cin >> f.denominator;

	return is;
}

ostream& operator<<(ostream& os, const Fraction& f)
{
	cout << f.numerator << " / " << f.denominator;
	
	return os;
}



Last edited on
did you #include <iostream> ?
In the header file you should #include <iosfwd> and in the cpp #include <iostream>
It seems to work now I included <iosfwd>
What is iosfwd?

EDIT:
It still doesn't work. As soon as I try to cout my object, I get this at compiling:
error LNK2019: unresolved external symbol "class Fraction __cdecl frac1(void)" (?frac1@@YA?AVFraction@@XZ) referenced in function _main

EDIT2:
And I get an error when I try to use the + operator:
error C2784: 'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'overloaded-function'
1> d:\program files\microsoft visual studio 9.0\vc\include\string(60) : see declaration of 'std::operator +'

I get these with a lot of my overloaded operators...

And when I try to use *, I get this:
no global operator found which takes type 'Fraction' (or there is no acceptable conversion)

But I have overloaded * :S
Last edited on
Ok, now I'm VERY confused. I've tried to cout my object again and.. it works now.

BUT now cin doesn't work:
c:\users\bjorn\documents\visual studio 2008\projects\fraction\fraction\fraction.h(25): or 'std::istream &operator >>(std::istream &,Fraction &)' [found using argument-dependent lookup]
1> while trying to match the argument list '(std::istream, Fraction (__cdecl *)(void))'

I still can't get the other operators to work =(

Oh, and Duoas, it's vacation here =)
Last edited on
<iosfwd> just forward declares the streams. The difference is that <iosfwd> needs to include far less than <iostream>. In very large applications including <iostream> in headers can increase compile times.

Anyway...

Part of your problem is that conversion operators suck. Don't use them. Instead, write a method called "get() const" to return the value.

Have you:

1) put "friend istream& operator>>( istream&, Fraction& );" in your class declaration?
2) implemented the method?

Yes, I did both (like you can see in my code above). But cout works now, cin doesn't :(
Last edited on
Neither should work.
See my comments about the I/O operators here
http://www.cplusplus.com/forum/beginner/12552/page1.html#msg60134

Hope this helps.
Last edited on
I did read that post yes... but what's the difference between my overloaded << and yours, except for the variable names? Why shouldn't it work (and why is it actually working)?
Okay, I now have this:

1
2
3
4
5
Fraction frac1();
Fraction frac2(2.0, 1.0);

	
cout << frac1 << endl;


My constructor:
1
2
3
4
5
Fraction::Fraction()
{
	numerator = 0.0;
	denominator = 1.0;
}


This gives this error:
1
2
1>Main.obj : error LNK2019: unresolved external symbol "class Fraction __cdecl frac1(void)" (?frac1@@YA?AVFraction@@XZ) referenced in function _main
1>C:\Users\Bjorn\Documents\Visual Studio 2008\Projects\Fraction\Debug\Fraction.exe : fatal error LNK1120: 1 unresolved externals


BUT

This:
1
2
3
4
5
Fraction frac1();
Fraction frac2(2.0, 1.0);

	
cout << frac2 << endl;

Compiles fine.

What's happening here?

Also (let's forget the cin for now, as I don't really understand it), this:
Fraction frac3 = frac1 + frac2;

gives this as an error:
1
2
c:\users\bjorn\documents\visual studio 2008\projects\fraction\fraction\main.cpp(12) : error C2784: 'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'overloaded-function'
1>        d:\program files\microsoft visual studio 9.0\vc\include\string(60) : see declaration of 'std::operator +'

But again, this compiles fine if I don't use the default constructor (see code above). So something is wrong with the constructor, but what?
Last edited on
The line

 
Fraction frac1();


is declaring a function named frac1 that takes no parameters and returns a Fraction.

Change to

 
Fraction frac1;


I did read that post yes...

I don't believe you.

but what's the difference between my overloaded << and yours, except for the variable names? Why shouldn't it work (and why is it actually working)?

My post directly answers, in detail, those very questions.


Stop grubbing about for quick answers and start thinking about what it is you are doing. Computer programming requires you to think.

For example, your compiler is complaining about the line Fraction frac3 = frac1 + frac2;.
Whenever you see Foo1 + Foo2, you should also be able to find what it means to use + on a Foo. If you don't tell the computer, how is it to know? (It is too stupid to figure it out on its own.)

So, what does it mean to add two fractions?

Figure it out and write an overloaded + operator to tell the computer how to add two fractions. Here's some help:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Fraction operator + ( const Fraction& left, const Fraction& right )
{
	// This is the Fraction we intend to have the sum of the two argument fractions
	Fraction result;

	// This is where you must do what is necessary to add the two fractions.
	// Put the results in the result variable.

	// Think back to grade school when fraction arithmetic was taught:
	// http://www.helpwithfractions.com/adding-fractions-different-denominators.html
	...

	// All done! Return the final answer.
	return result;
}
(Remember that that operator should be a friend of your Fraction class.)

If you insist on using float for your numerator and denominator fields (which I have already dis-recommended to you), you will not be able to find the GCD. You will instead have to use some simple algebra on the source fractions to get a common denominator...


Now, unless you can put some real effort into this I will not answer further. (I've already given you an significant amount of help.)

Good luck!
I don't believe you.

...

My post directly answers, in detail, those very questions.

Oh?

This is how it should look (your code!):
ostream& operator << ( ostream& outs, const Fraction& frac )

And mine looks exactly like that. Yes, I didn't add a check for negatives, but I'm just trying to learn about overloading operators. I assume I only work with positives. I compiled, I did get an error. I closed VC++, compiled again without changing the code, and it compiled fine. Now, where did you explain this in detail?

Stop grubbing about for quick answers and start thinking about what it is you are doing. Computer programming requires you to think.

For example, your compiler is complaining about the line Fraction frac3 = frac1 + frac2;.
Whenever you see Foo1 + Foo2, you should also be able to find what it means to use + on a Foo. If you don't tell the computer, how is it to know? (It is too stupid to figure it out on its own.)

Now, where did I tell you that I didn't write code on how it should use +? I actually did and my code works fine, as mentioned in my post above. There is/was just something wrong with my constructor.

So, what does it mean to add two fractions?

Figure it out and write an overloaded + operator to tell the computer how to add two fractions. Here's some help:

I'm not stupid. I did write that code.

(Remember that that operator should be a friend of your Fraction class.)

I've learned it just just be a method of the class, not a friend. Is there any reason it should be a friend and not a normal method?


If you insist on using float for your numerator and denominator fields (which I have already dis-recommended to you), you will not be able to find the GCD. You will instead have to use some simple algebra on the source fractions to get a common denominator...

Good, I'll make integers of them. And again, this is not about the fractions. I'm just trying to understand operator overloading.


Now, unless you can put some real effort into this I will not answer further. (I've already given you an significant amount of help.)

I DID put some real effort into this. You just jump to some strange conclusions like I didn't write code to overload the + operator.

Good luck!

Thank you.

@Jsmith: Thanks, I'll have a look at it =)

EDIT:
Thank you Jsmith, that indeed solved all the errors. I'll test all my code this afternoon.
Last edited on
Topic archived. No new replies allowed.