1

我有一些可以正常工作的代码,但我想确保它在 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);
}
4

2 回答 2

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 函数放在同一个命名空间中。

于 2013-08-29T20:32:10.350 回答
0

与使用转换为 double 相比,特定的重载将是更好的匹配(或精确的如果const不需要添加),因此将调用正确的版本。

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

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

于 2013-08-29T20:28:26.000 回答