c++ - 非表示 - テンプレートコードの「0で割る」エラーを取り除く方法




関数 divide のパラメータ 2 にはゼロ以外を指定してください。 (2)

Visual Studioはコンパイル時に3値演算でB1、B2を型キャストできませんが、明示的にキャストするとうまくいきます。

template<int B1, int B2>
class MyClass
{
    double d1 = (double)B1;
    double d2 = (double)B2;
    const double B = (B2 == 0) ? 0.0 : d1/d2;
    // ...
};

MyClass<0, 0> myobj;

テンプレートパラメータとしてdoubleを使用することはできないので、比率を指定するために整数テンプレートパラメータのペアを使用しています。 倍精度への変換は、3進数によるゼロ除算から保護されています。 これは以前のバージョンのコンパイラで機能しましたが、Visual Studio 2013ではエラーが発生しました。

error C2124: divide or mod by zero

これがコードの簡略版です。

template<int B1, int B2>
class MyClass
{
    const double B = (B2 == 0) ? 0.0 : (double) B1 / (double) B2;
    // ...
};

MyClass<0, 0> myobj;

私は本当にBがゼロのときにそれを使う式から最適化されることを望むので、私は単一行の定義が必要です。 それを回避するためにテンプレートパラメータ<0, 1>を使用することができますが、私の表現は安全であるとコンパイラに納得させる方法があるのだろうか。


好奇心が強い人のために - これが私がついに終わったコードです。 現実世界の状況でそれを見ることはおそらく役に立つでしょう。

template<int B1, int B2, int C1, int C2>
class BicubicFilter
{
    // Based on the formula published by Don Mitchell and Arun Netravali at
    // http://www.cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/mitchell/Mitchell.pdf
public:
    BicubicFilter() : m_dMultiplier(1.0) {}
    double m_dMultiplier;
    double k(double x) const
    {
        const double B = (double) B1 / ((B2 == 0) ? 1.0 : (double) B2);
        const double C = (double) C1 / ((C2 == 0) ? 1.0 : (double) C2);
        x = fabs(x) * m_dMultiplier;
        if (x < 1.0)
            return ((2.0 - 1.5*B - C) * x*x*x) + ((-3.0 + 2.0*B + C) * x*x) + (1.0 - (2.0/6.0)*B);
        if (x < 2.0)
            return (((-1.0/6.0)*B - C) * x*x*x) + ((B + 5.0*C) * x*x) + ((-2.0*B - 8.0*C) * x) + ((8.0/6.0)*B + 4.0*C);
        return 0.0;
    }
};

画像サイズ変更操作のために、 k関数は1ピクセルあたり少なくとも4回実行されるので、効率は重要である。 コンパイラーが式をできるだけ単純化できるように、コンパイル時にすべての定数を知っておきたいのです。

受け入れられた答えに基づいて、私は単に2つのintの比率をconstexpr doubleとして生成し、それを0, 0パラメータに特化するRatioテンプレートクラスを作成することを望んでいました。 Visual Studio 2013はまだconstexpr実装していないので、コンパイラがそれをコンパイル時定数として扱うとは確信していませんでした。 幸いなことに、元の3項式を変更することでエラーを解消できました。





divide-by-zero