Can we overload operators for built-in types like int or float?
You cannot redefine a built-in operator. Operator overloading
is designed to allow you to extend the language, not to change
it. At least one of the parameters of an overloaded operator
must be a user defined type (class or enum type) or a reference
to a user defined type.
Can we overload operators for built-in types like int or float?
You cannot redefine a built-in operator. Operator overloading
is designed to allow you to extend the language, not to change
it. At least one of the parameters of an overloaded operator
must be a user defined type (class or enum type) or a reference
to a user defined type.
How to overload an operator for integer, float and double data types simultaneously in C++
Separate solution than the template solution is to define constructors for the types you want to support, and have a single operator+ that works on Point types.
The compiler will implicitly call the proper constructor to convert the built-in type, before invoking operator+.
This simplifies the implementation, at the expense of wasted temp objects.
// Example program
#include <iostream>
#include <string>
class Point {
private:
double x, y;
public:
Point(int val) {
this->x = val;
this->y = val;
}
Point(double x, double y) {
this->x = x;
this->y = y;
}
friend Point operator+(const Point &p1, const Point &p2) {
return Point(p1.x + p2.x, p1.y + p2.y);
}
};
int main()
{
Point p(1,2);
Point q = p + 10;
Point v = 10 + p;
}
There is a stylistic argument about explicitly white-listing supported types via the constructors, and blacklisting via static_asserts.
How to overload operators with a built-in return type?
Based on your example, what you really want is an implicit conversion operator:
class Test
{
// ...
public:
operator float() const;
};
inline Test::operator float() const
{
return mIsFloat ? mFloat : mInt;
}
If you want to conditionally do the assignment, then you need to take another approach. A named method would probably be the best option, all things considered... something like this:
class Test
{
public:
bool try_assign(float & f) const;
};
inline bool Test::try_assign(float & f) const
{
if (mIsFloat) {
f = mFloat;
}
return mIsFloat;
}
Whatever you do, be careful that the syntactic sugar you introduce doesn't result in unreadable code.
Overloading operator% for floating types
You can't overload operators for primitive types the way you'd want it to work.
For C++11 draft n3290, §13.5 Operator Overloads, point 6:
An operator function shall either be a non-static member function or be a non-member function and have at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration. [...]
Primitive types aren't classes (or enums), so they can't have member functions. And you can't create a global float operator%(float&,float&)
since that doesn't involve a class or enum in the parameter list. (See also C++FAQ 26.10 "Can I define an operator overload that works with built-in / intrinsic / primitive types?".)
You need at least one of the terms in the %
expression to be a user-defined type.
You could create a class Float
and define whatever operations you want on it, but you cannot get a = a % b;
to use your function if both a
and b
are float
s.
Or you could #include <cmath>
and use std::fmod
:
#include <iostream>
#include <cmath>
int main()
{
float a = 13.0f;
float b = 5.0f;
a = std::fmod(a, b);
std::cout << a << std::endl;
return 0;
}
Simple example with a custom "float wrapper" (incomplete, probably not quite safe as-is, but can get you started):
#include <iostream>
#include <cmath>
class Float {
private:
float val;
public:
Float(float f): val(f) {};
Float operator%(Float const& other) const {
return std::fmod(val, other.val);
}
Float operator%(float const& other) const {
return std::fmod(val, other);
}
// conversion operator could be handy
operator float() { return val; }
};
int main()
{
Float a = 13.0f;
Float b = 5.0f;
Float c = a % b;
std::cout << c << std::endl;
// this also works
Float d = 13.0f;
float e = 5.0f;
float f = d % e;
std::cout << f << std::endl;
return 0;
}
Resolution of built-in operator == overloads
This is CWG 507. An example similar to yours was given, and the submitter explained that according to the standard, the overload resolution is ambiguous, even though this result is very counter-intuitive.
Translating to your particular example, when comparing operator==(int, int)
and operator==(float, int)
to determine which is the better candidate, we have to determine which one has the better implicit conversion sequence for the first argument (obviously in the second argument, no conversion is required). For the first argument of operator==(int, int)
, we just use A::operator int
. For the first argument of operator==(float, int)
, there is no way to decide whether to use A::operator int
or A::operator char
, so we get the "ambiguous conversion sequence". The overload resolution rules say that the ambiguous conversion sequence is no better or worse than any other user-defined conversion sequence. Therefore, the straightforward conversion from A{}
to int
(via A::operator int
) is not considered better than the ambiguous conversion from A{}
to float
. This means neither operator==
candidate is better than the other.
Clang is apparently following the letter of the standard whereas GCC and MSVC are probably doing something else because of the standard seeming to be broken here. "Which compiler is right" depends on your opinion about what the standard should say. There is no proposed resolution on the issues page.
I would suggest removing operator char
unless you really, really need it, in which case you will have to think about what else you're willing to give up.
Overloading operator whose parameter is not class or enum
I want to overload operator like this:
fraction operator / (int a, int b) // error here
You may not do what you want, as the compiler says.
Can I get around this?
Want something else. There's no way to change division of two int
in C++.
You can just write fraction(1, 3)
. If you would like something shorter to write, then you could use a user defined literal: 1_frac / 3
.
not fraction(1/3) (1/3 which equal 0.3333333 in float so when converting back into fraction
1/3 is not a float. It equals 0.
Related Topics
Concatenate Two String Literals
Redirect Stdout/Stderr to a String
C++ Access Static Members Using Null Pointer
What Does Template <Unsigned Int N> Mean
Altering Dll Search Path for Static Linked Dll
When to Use Std::Forward to Forward Arguments
Undefined Symbols "Vtable for ..." and "Typeinfo For..."
Unnecessary Curly Braces in C++
C++ Program Converts Fahrenheit to Celsius
When Do We Have to Use Copy Constructors
What's the Meaning of Exception Code "Exc_I386_Gpflt"
Start Windows Service from Application Without Admin Right(C++)
Get the Compiler Options from a Compiled Executable
How to Compare Multiple Strings Inside an If Statement
Force to Link Against Unused Shared Library
Statically Linking System Libraries, Libc, Pthreads, to Aid in Debugging
How to Know If One Shared Library Depends on Another Shared Library or Not