【问题标题】:initialize an array of compile-time constant size with incrementing numbers用递增的数字初始化一个编译时常量大小的数组
【发布时间】:2019-01-21 09:14:05
【问题描述】:

我有一个数组,它的大小是使用编译时常量设置的(在我的例子中是预处理器#define)。我需要在编译时使用连续数字对其进行初始化。我该怎么做?

简化示例:

#define ARR_SZ 5
struct C {
  C(int a) : a(a) {}
  int a;
};
C arr[ARR_SZ] = {{0},{1},{2},{3},{4}}; // This needs to adapt to any number

我可以使用 C++11,但不是更新的(尽管我有兴趣学习更新的技术,即使我不能在这个项目中使用它们)

【问题讨论】:

  • 可以是std::array而不是原始数组吗?
  • std::make_index_sequence (C++14)(可以用C++11实现)。
  • @StoryTeller 在实际代码中,它是一个std::array,并且是一个没有默认构造函数并且只有一个接受整数的构造函数的类类型。我试图简化
  • 使用没有默认构造函数的类可能会产生很大的不同。始终尝试创建一个minimal reproducible example 向我们展示,不要简化太多。

标签: c++ c++11


【解决方案1】:

C++14 代码(因为std::integer_sequence):

#include <type_traits>
#include <array>

#define ARR_SZ 5
struct C {
  C(int a) : a(a) {}
  int a;
};

template<int ...Is>
auto make_C_arr(std::integer_sequence<int, Is...>) -> std::array<C, sizeof...(Is)> {
    return {{ {Is}... }};
}

auto arr = make_C_arr(std::make_integer_sequence<int, ARR_SZ>{});

int main () {

}

【讨论】:

  • 可以在没有额外的函数调用 (make_C_arr) 的情况下完成吗?它看起来很丑
  • @Baruch - 不,不是这个。有些东西需要拆包。如果您愿意,可以尝试使用预处理器。
  • 为什么需要双括号? ({{ {Is}.. }} 而不是{ {Is}.. }
【解决方案2】:

由于在评论部分提到了 boost,这里是另一个基于 Boost.PP 的完全不同的解决方案。它也完全是 C++03。

#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>

#define ARR_SZ 5
struct C {
  C(int a) : a(a) {}
  int a;
};

#define INIT(z, n, d) BOOST_PP_COMMA_IF(n) C(n)

C arr[ARR_SZ] = { BOOST_PP_REPEAT(ARR_SZ, INIT, ?) };


int main () {

}

BOOST_PP_REPEAT 将扩展为 INIT(z, 0, ?) ... INIT(z, 4, ?)z 与我们的目标无关,? 令牌只是一个占位符。由于INIT 依次扩展为C(n)n 从 0 到 4(逗号分隔),我们得到了一个常规 C 样式数组的初始化器。

【讨论】:

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