简体   繁体   中英

C++ overloaded functions and implicit casts

I have some code that works correctly, but I want to make sure that it will always work correctly under the C++ standard.

I've created two types which are implicitly converted to double, and created a sin() function for each of the types. I tested it and the correct sin() overload is called, but is it guaranteed that the compiler will not decide to cast the object instance implicitly to double and call the math.h functions?

In addition, does it matter if my classes and sin() overloads are in a namespace? Will it matter if I template any of them?

struct AngleDegrees;
struct AngleRadians;

inline double degs2Rads(double degs) { return degs * PI / 180.0; }
inline double rads2Degs(double degs) { return degs * 180.0 / PI; }

struct AngleDegrees
{
private:
    double m_val;

public:
    explicit AngleDegrees(double val) : m_val(val) { }
    explicit AngleDegrees(const AngleRadians& rads);

    operator double() const { return m_val; }
};

struct AngleRadians
{
private:
    double m_val;

public:
    explicit AngleRadians(double val) : m_val(val) { }
    explicit AngleRadians(const AngleDegrees& degs);

    operator double() const { return m_val; }
};

inline AngleDegrees::AngleDegrees(const AngleRadians& rads)
{
    m_val = rads2Degs(rads);
}

inline AngleRadians::AngleRadians(const AngleDegrees& degs)
{
    m_val = degs2Rads(degs);
}

inline double sin(const AngleDegrees& degs)
{
    std::cout << "called sin(AngleDegrees)\n";
    AngleRadians rads(degs);
    return sin((double)rads);
}

inline double sin(const AngleRadians& rads)
{
    std::cout << "called sin(AngleRadians)\n";
    return sin((double)rads);
}

I would remove the implicit conversions and use member functions instead. Surely the reason for these classes is to avoid the problems of having variables that could be in one unit or another?

Take a look at the Ogre framework, for example: http://www.ogre3d.org/docs/api/html/classOgre_1_1Radian.html http://www.ogre3d.org/docs/api/html/classOgre_1_1Degree.html

As for namespacing the functions, take a look at ADL: http://en.wikipedia.org/wiki/Argument-dependent_name_lookup you can put the classes and sin functions in the same namespace.

The specific overloads will be a better match (or exact if const doesn't need to be added) than using the conversion to double so the correct version will be called.

That said, put the code in a namespace and let ADR find the right functions to avoid any possible confusion.

EDIT: You might consider using the boost units framework to help you here instead of coding it yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM