1

これがループです。基本的に、円の円周に沿って一定数の点を生成します。ポイント配列は明らかに定数であり、コンパイル時に計算できますが、それをconstexprに巻き上げる方法がわかりません。

#include <array>
#include <cmath>

template <std::size_t Len>
class Circle {
public:
    Circle() {
        for (int i = 0; i < Len; i++) {
            float x = (float)std::cos(2 * M_PI * i / (Len - 1));
            float y = (float)std::sin(2 * M_PI * i / (Len - 1));
            points[i * 3] = x;
            points[i * 3 + 1] = y;
            points[i * 3 + 2] = 0;
        }
     }
 private:
     std::array<float, Len * 3> points;
 };
4

2 に答える 2

3

厳密に正確であるとは限りませんが、目的には十分である可能性があります。

テイラー級数近似を使用しました。追加constexprして、それらが機能するかどうかを確認します。

long double sin2r(long double const r, long double const t, long double const tn, unsigned long long k)
{
    return tn == 0 ? r : sin2r(r + ((k / 2) % 2 ? -1 : +1) * tn, t, tn * t * t / ((k + 1) * (k + 2)), k + 2);
}

long double cos2r(long double const r, long double const t, long double const tn, unsigned long long k)
{
    return tn == 0 ? r : cos2r(r + ((k / 2) % 2 ? -1 : +1) * tn, t, tn * t * t / ((k + 1) * (k + 2)), k + 2);
}

long double sin2(long double const t)
{
    return sin2r(0, t, t, 1);
}

long double cos2(long double const t)
{
    return cos2r(0, t, 1, 0);
}
于 2012-12-01T08:42:05.013 に答える
2

まず第一に、constexpr関数は必ずしもコンパイル時に評価されるとは限りません。コンパイラがこれを行わなければならない場合があります (例: コンパイル時定数として使用される場合)。しかし、標準はそのようなことを必要としません。(理論的には、生成コードを格納して起動時に 1 回実行することが簡単で、 の計算値を格納するよりも使用するスペースが少ない場合、コンパイラはこれを行う必要がありますconstexpr) 。

第二に、あなたの例は作ることができませんconstexpr。標準では、constexpr関数は他の関数のみを呼び出す必要constexprがあり、形式はreturn expression;です。sinand cosconstexpr関数ではない)に依存しており、形式ではないループが必要なため、例はどちらの条件も満たしていませんreturn expression;

constexpr最適化のために設計されていません。コンパイル時の定数を計算できるように設計されています (たとえば、スタックに割り当てられた配列のサイズとして結果を使用できるようにするため)。

于 2012-12-01T08:03:21.553 に答える