How to Overload Operators for Built-In Types Like Int or Float

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 floats.

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



Leave a reply



Submit