C ++重载函数和隐式转换

时间:2013-08-29 20:23:26

标签: c++ implicit-conversion overload-resolution

我有一些代码可以正常工作,但我想确保它在C ++标准下始终可以正常工作。

我创建了两种隐式转换为double的类型,并为每种类型创建了一个sin()函数。我测试了它并且调用了正确的sin()重载,但它是否保证编译器不会决定隐式地将对象实例强制转换为double并调用math.h函数?

此外,如果我的类和sin()重载在命名空间中,这是否重要?如果我模板中的任何一个都有意义吗?

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);
}

2 个答案:

答案 0 :(得分:2)

我会删除隐式转换并使用成员函数。当然,这些类的原因是为了避免变量可能在一个单元或另一个单元中的问题?

看看Ogre框架,例如: http://www.ogre3d.org/docs/api/html/classOgre_1_1Radian.html http://www.ogre3d.org/docs/api/html/classOgre_1_1Degree.html

至于命名空间函数,请看一下ADL:http://en.wikipedia.org/wiki/Argument-dependent_name_lookup,你可以将类和sin函数放在同一个命名空间中。

答案 1 :(得分:0)

特定的重载将更好地匹配(或者如果不需要添加const则完全匹配),而不是使用转换加倍,以便调用正确的版本。

也就是说,将代码放在命名空间中,让ADR找到合适的函数以避免任何可能的混淆。

编辑:您可以考虑使用boost unit框架来帮助您而不是自己编码。