如何将模板大小的数组初始化转换为constexpr初始化?

时间:2012-12-01 07:17:30

标签: c++ c++11

这是循环。基本上沿圆周产生一定数量的点。点数组显然是恒定的&可以在编译时计算,但我似乎无法找到一种方法将其提升为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;
 };

2 个答案:

答案 0 :(得分:3)

它们不能保证严格准确,但它们可能足以满足您的目的。

我刚刚使用了Taylor系列近似值。添加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);
}

答案 1 :(得分:2)

首先,constexpr函数不一定在编译时进行评估。在某些情况下,编译器必须这样做(例如,如果该东西用作编译时常量);但标准并不要求这样的事情。 (理论上,编译器可能希望这样做,如果存储生成代码并在启动时运行一次是微不足道的,并且使用的空间少于存储constexpr的计算值

其次,您的示例无法生成constexpr。该标准要求任何constexpr函数仅调用其他constexpr函数,并且格式为return expression;。您的示例不符合条件,因为您依赖于sincos(不是constexpr函数),并且您需要一个不是return expression;形式的循环

constexpr不是为优化而设计的;它旨在允许您计算编译时常量(例如,以便您可以将结果用作堆栈分配数组的大小)。