c++function-declarationcustom-type

Defining multiple functions with the same name using custom types


I've been playing around with C++ and I've noticed something that I don't quite understand:

typedef float degrees;
typedef float radians;

void my_func(degrees n);
void my_func(radians m);

Declaring a function like this, I get a warning that the function is re-declared as if they are identical. Does this mean, when looking at function definitions, the compiler only sees built-in types and doesn't care about custom defined types, and since they're bot floats, it just considers them to be the same function?...

If that's the case, how do I get around this? Do I just have to make a different function?


Solution

  • Another possibility is to define Radian and Degree classes to have an explicit conversion from floats and an implicit conversion to them.

    class Radian{
        float m_value;
    public:
        explicit Radian(float t_value) : m_value(t_value) { }
        operator float() const { return m_value; }
    };
    
    class Degree{
        float m_value;
    public:
        explicit Degree(float t_value) : m_value(t_value) { }
        operator float() const { return m_value; }
    };
    
    void my_func(Radian r);
    void my_func(Degree d);
    
    my_func(Radian(10)); // calls the Radian overload
    my_func(Degree(10)); // calls the Degree overload
    my_func(10); // Doesn't call either because both ctors are explicit
    
    
    

    The implicit conversions to float mean that you can pass a variable of type Radian or Degree to a function expecting float and it'll just work.


    This version does mean that, unlike the typedefs, you won't be able to write things like

    Degree alpha = 30;
    Degree beta = 60;
    Degree gamma = alpha + beta; // 90 degrees
    

    However, if you want, you can also define arithmetic operators like operator+, operator*, etc for each class. For instance, you might want to always perform Degree arithmetic modulo 360, so that 180 + 180 = 0.