【问题标题】:Initialize C-style array with non-zero value without loops用非零值初始化 C 样式数组而不使用循环
【发布时间】:2016-04-23 12:24:31
【问题描述】:

我们知道 C++ 允许initialization of C-style arrays with zeros:

int a[5] = {0};
// or
int a[5] = {};

同样适用于 std::array

std::array a<int, 5> = {};

但是,这不起作用:

int a[5] = {33}; // in memory( 33, 0, 0, 0, 0 )
std::array<int, 5> = {33}; // in memory( 33, 0, 0, 0, 0 )

有没有办法在不使用vectoralgorhtm 的情况下用非零值初始化整个数组?

也许constexpr 能帮上忙?最好的解决方案是什么?

附:

GCC 提供this syntax

int a[5] = {[0 ... 4] = 33};

但我不确定它是否对其他编译器有效。

【问题讨论】:

  • 也许你需要收紧要求,因为int a[5] = {33, 33, 33, 33, 33};
  • 好吧,谷歌搜索你的确切标题会得到:'大约 1,470,000 个结果'。也许里面有些东西可能有用。
  • @LightnessRacesinOrbit 就我个人而言,我更喜欢这样的限定词,它使 IMO 的讨论更加清晰。
  • @LightnessRacesinOrbit 人们,即使是程序员,也很少会说或用英语输入命名空间。讨论向量、映射和集合是很常见的,即使在 C++ 中,这些东西只存在于 std 命名空间中。人们也讨论数组,根据上下文,他们可能指的是数组的任何一种形式,甚至是也是对象数组的向量。因此,需要一种方法来消除该术语的歧义。
  • 从 C 风格改为 C 风格

标签: c++ arrays


【解决方案1】:

你对&lt;algorithm&gt; 有什么看法?我认为这很干净:

int a[5];                                  // not initialized here yet
std::fill(std::begin(a), std::end(a), 33); // everything initialized to 33

【讨论】:

  • 没什么私人的,这更像是一个理论问题。我们有一种适用于零的特定语法,有没有类似的东西可能适用于非零。
【解决方案2】:

我有一些代码可以使用模板元编程(当然)实现std::array 的编译时初始化。

namespace impl {

    template <class SeqTy, size_t N, SeqTy FillVal, SeqTy... Seq>
    struct make_fill {
        using type = typename make_fill<SeqTy, N-1, FillVal, FillVal, Seq...>::type;
    };

    template <class SeqTy, SeqTy FillVal, SeqTy... Seq>
    struct make_fill<SeqTy, 0, FillVal, Seq...> {
        using type = std::integer_sequence<SeqTy, Seq...>;
    };

    template <class T>
    struct make_array;

    template <class SeqTy, SeqTy... Seq>
    struct make_array<std::integer_sequence<SeqTy, Seq...>> {
        static constexpr std::array<SeqTy, sizeof...(Seq)> value() { 
            return std::array<SeqTy, sizeof...(Seq)>{ {Seq...} };
        }
    };

} // end impl namespace

template <class SeqTy, size_t N, SeqTy FillVal = 0ul>
constexpr std::array<SeqTy, N> fill() {
    return impl::make_array<typename impl::make_fill<SeqTy, N, FillVal>::type>::value();
};

你可以按如下方式使用:

std::array<size_t, N> ones = fill<size_t,N,1ul>();

如果你不想使用std::array,我认为你可以轻松适应它

【讨论】:

  • 我必须承认我的问题对 std::array 也有效;在那里应用相同的初始化规则。你的答案几乎就是我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-01
  • 2014-05-24
  • 1970-01-01
  • 2013-10-20
  • 1970-01-01
  • 2020-12-25
  • 1970-01-01
相关资源
最近更新 更多