1

正しく動作するコードがいくつかありますが、C++ 標準の下で常に正しく動作することを確認したいと考えています。

暗黙的に double に変換される 2 つの型を作成し、各型に対して 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 フレームワークを見てみましょ

関数の名前空間については、ADL を参照してください: http://en.wikipedia.org/wiki/Argument-dependent_name_lookupクラスと sin 関数を同じ名前空間に配置できます。

于 2013-08-29T20:32:10.350 に答える
0

const特定のオーバーロードは、double への変換を使用するよりも一致する (または追加する必要がない場合は完全に一致する) ため、正しいバージョンが呼び出されます。

つまり、コードを名前空間に配置し、ADR が適切な関数を見つけて混乱を避けるようにします。

編集:自分でコーディングする代わりに、ブーストユニットフレームワークを使用してここで役立つことを検討してください。

于 2013-08-29T20:28:26.000 に答える