【问题标题】:Initialize array whose size is a compile-time constant to single value将大小为编译时常量的数组初始化为单个值
【发布时间】:2019-10-15 23:00:27
【问题描述】:

我有一个 c 样式数组,其大小由 #define 定义,并且可以根据编译选项进行更改,例如

#if LINUX
# define SIZE 4
#else
# define SIZE 5
#endif
static int myArr[SIZE] = { /* ??? */ };

如何将整个数组初始化为非零值,例如所有42

【问题讨论】:

  • @SamerTufail: memset 是运行时,OP 搜索编译时间我要离开!
  • #define V 42 #define INIT4 V, V, V, V #define INIT6 INIT4 , V, V 然后将#define INIT <XXX> 放在那些#ifelses 中太笨了吗? static int myArr[] = { INIT}; 不是很漂亮,但它完成了工作。
  • 可以切换到std::array 吗?
  • 那么使用像Boost.PP这样的库怎么样?
  • 我以为我有一种似曾相识的感觉stackoverflow.com/questions/54286610/…

标签: c++ c++11


【解决方案1】:

我不知道 C 样式数组的解决方案,但使用 constexpr 和 C++17 你可以使用 std::array 做到这一点。

constexpr std::array<int, SIZE> createFilledArray (int value){
   std::array<int, SIZE> a{0};
   for (auto i = 0; i < SIZE; ++i)
       a[i] = value;
   return a;
}

static constexpr auto myArr = createFilledArray(42);

Code at compiler explorer

这样做的缺点是不能更改数组。 如果你从变量中删除constexpr,你的编译器应该能够优化它。

从 C++20 开始,您可以强制初始化:

static constinit auto myArr = createFilledArray(42);

不确定提案是否已合并:请参阅constinit proposal

【讨论】:

  • createFilledArray() 中的循环可以替换为a.fill(value)
  • std::array::fill 仅在 C++20 中声明为 constexpr
  • 我需要 C++11(如问题标签所述)
【解决方案2】:

如果你坚持使用内置数组,你可以在函数中使用静态变量:

template <std::size_t N, std::size_t... Is>
auto arr_helper2(std::index_sequence<Is...>) -> int (&)[N]
{
    static int arr[N] = {((void)Is, 42)...};
    return arr;
}

template <std::size_t N>
auto arr_helper() -> int (&)[N]
{
    return arr_helper2<N>(std::make_index_sequence<N>{});
}

static int (&arr)[SIZE] = arr_helper<SIZE>();

例如:

int main()
{
    for (std::size_t i = 0; i < SIZE; ++i)
        std::cout << arr[i] << " ";
}

live demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    • 2021-04-22
    • 2012-08-31
    • 1970-01-01
    • 2015-07-28
    相关资源
    最近更新 更多