有没有办法创建一个用循环初始化的 static const class 值?

Is there a way to create a static const class value that is initialized with a loop?

静态成员可以声明为const,但必须在声明中对其进行初始化。考虑以下使用循环代码初始化静态数组的情况:

class A {
private:
  enum { SIZE = 360 };
  static double* vertices;
public:
  static void staticInit();
};

double* A::vertices = new double[SIZE];
void A::staticInit() {
  double a = 0, b = 0;
  for (int i = 0; i < SIZE; i++, a += .01, b += .02)
    vertices[i] = sin(a) + c2 * sin(b);
}

上面的代码可以工作。但是如果目的是使顶点常量,那么将其声明为常量将在 staticInit 函数上产生编译错误。

在旧的 C++ 中,我会声明指针 const,并仅在此函数中将其转换为非常量,但今天,编译器不允许这样做,因为它不安全。当然,不声明指针const更不安全。

有什么干净的出路吗?

创建一个 makeVertices 函数 returns 一个 std::array,然后通过调用它来初始化 static 值:

constexpr std::size_t size = 360;

std::array<double, size> makeVertices()
{
    std::array<double, size> vertices;
    double a = 0, b = 0;

    for (int i = 0; i < size; i++, a += .01, b += .02)
        vertices[i] = sin(a) + c2 * sin(b);

    return vertices;
}

makeVerticessize都可以定义在A里面。)

class A {
private:
  static std::array<double, size> vertices;
};

std::array<double, size> A::vertices = makeVertices();

还要注意使用 constexpr 而不是 enum 来表示编译时数值常量——这是 C++11 的惯用做法。

我不明白为什么你不能把你关心的一切都变成常量。简化用例:

const T * const p = Init();

T * Init()
{
    T * result = new T[n];
    for (std::size_t i = 0; i != n; ++i)
      InitOne(result[i]);
    return result;
}

您应该能够将此方案应用于您的静态 class 成员。