I have a class that encapsulates some arithmetic, let's say fixed point calculations. I like the idea of overloading arithmetic operators, so I write the following:
class CFixed
{
CFixed( int );
CFixed( float );
};
CFixed operator* ( const CFixed& a, const CFixed& b )
{ ... }
It all works. I can write 3 * CFixed(0) and CFixed(3) * 10.0f. But now I realize, I can implement operator* with an integer operand much more effective. So I overload it:
CFixed operator* ( const CFixed& a, int b )
{ ... }
CFixed operator* ( int a, const CFixed& b )
{ ... }
It still works, but now CFixed(0) * 10.0f calls overloaded version, converting float to int ( and I expected it to convert float to CFixed ). Of course, I can overload a float versions as well, but it seems a combinatorial explosion of code for me. Is there any workaround (or am I designing my class wrong)? How can I tell the compiler to call overloaded version of operator* ONLY with ints?
Overview. Implicit type conversion in C language is the conversion of one data type into another datatype by the compiler during the execution of the program. It is also called automatic type conversion.
The operator overloading defines a type conversion operator that can be used to produce an int type from a Counter object. This operator will be used whenever an implicit or explict conversion of a Counter object to an int is required. Notice that constructors also play a role in type conversion.
Yes, there is something called implicit operator overloading. According to MSDN, an implicit keyword is used to declare an implicit user-defined type conversion operator. In other words, this gives the power to your C# class, which can accepts any reasonably convertible data type without type casting.
Implicit conversions: No special syntax is required because the conversion always succeeds and no data will be lost. Examples include conversions from smaller to larger integral types, and conversions from derived classes to base classes.
You should overload with float
type as well. Conversion from int
to user-specified type (CFixed
) is of lower priority than built-in floating-integral conversion to float
. So the compiler will always choose function with int
, unless you add function with float
as well.
For more details, read 13.3 section of C++03 standard. Feel the pain.
It seems that I've lost track of it too. :-( UncleBens reports that adding float only doesn't solve the problem, as version with double
should be added as well. But in any case adding several operators related to built-in types is tedious, but doesn't result in a combinatorial boost.
If you have constructors which can be invoked with just one argument, you effectively created an implicit conversion operator. In your example, wherever a CFixed
is needed, both an int
and a float
can be passed. This is of course dangerous, because the compiler might silently generate code calling the wrong function instead of barking at you when you forgot to include some function's declaration.
Therefore a good rule of thumb says that, whenever you're writing constructors that can be called with just one argument (note that this one foo(int i, bool b = false)
can be called with one argument, too, even though it takes two arguments), you should make that constructor explicit
, unless you really want implicit conversion to kick in. explicit
constructors are not used by the compiler for implicit conversions.
You would have to change your class to this:
class CFixed
{
explicit CFixed( int );
explicit CFixed( float );
};
I have found that there are very few exceptions to this rule. (std::string::string(const char*)
is a rather famous one.)
Edit: I'm sorry, I missed the point about not allowing implicit conversions from int
to float
.
The only way I see to prevent this is to provide the operators for float
as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With