在启动时填充全局静态数组

时间:2019-06-23 06:07:46

标签: c++ arrays c++14

除了在源中指定其元素的详尽列表(膨胀源和二进制文件)之外,如何在启动时填充静态数组?

这是我想出的最好的方法,可以动态地将array的值填充为0到99:

int array[100];

struct FillArray {
    FillArray() {
        std::iota(std::begin(array), std::end(array), 0);
    }
};

FillArray dummy;

那里还有一种更惯用的方式吗?

数组的定义不能更改:它必须看起来像是静态数组来调用代码(例如,不建议使用std::array)。


请注意,我不是要解决静态初始化顺序问题。也就是说,您可以假设除了初始化之外,直到main()开始之后才可以再次访问该数组。

1 个答案:

答案 0 :(得分:1)

您要查找的是Schwarz Counter的某些版本(又称Nifty Counter)。

Nifty计数器用于在程序中首次使用之前初始化非本地静态对象,并在最后一次使用之后销毁它。

std :: cout是std库中一个Nifty Counter的示例。

以下是您的用例示例:

// GlobalArray.hpp

#pragma once

#include <array>

struct GlobalArray // This the the struct containing the 'static' object we want 
{
    GlobalArray();
    ~GlobalArray();
    std::array<int, 100> array;

};
extern GlobalArray& global_array; // This is the variable containing the reference to the constructed 'static' object. 

static struct GlobalArrayInit
{
    GlobalArrayInit();
    ~GlobalArrayInit();
} global_array_init;

现在...

// GlobalArray.cpp

#include "GlobalArray.hpp"

static int nifty_counter; // zero initialised at load time
static typename std::aligned_storage<sizeof (GlobalArray), alignof (GlobalArray)>::type
  global_array_buf; // memory for the global_array object
GlobalArray& global_array = reinterpret_cast<GlobalArray&> (global_array_buffer);

GlobalArray::GlobalArray ()
{
  // initialize things
}
GlobalArray::~GlobalArray ()
{
  // clean-up
} 

GlobalArrayInit::GlobalArrayInit ()
{
  if (nifty_counter++ == 0) new (&global_array) GlobalArray (); // placement new
}
GlobalArrayInit::~GlobalArrayInit ()
{
  if (--nifty_counter == 0) (&global_array)->~GlobalArray ();
}

请注意,在使用'global_array'对象之前,您必须包含标头,以确保其构造正确。

如果您想进一步了解它的工作方式以及我对源代码的了解,请阅读以下内容:https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter