C ++将静态成员std :: array元素初始化/填充为特定值

六角冠

我想知道是否有适当的方法来做到这一点。

给出示例:

struct Test {
    static std::array<unsigned, 123> data;
};

std::array<unsigned, 123> Test::data = {};

如果我想将中的所有元素设置data为某个值,例如5。

我可以做这样的事情:

struct Test {
    static std::array<unsigned, 123> data;
private:
    static decltype(data) init_data_arr() {
        decltype(data) arr = {};
        arr.fill(5);
        return arr;
    }
};

std::array<unsigned, 123> Test::data = Test::init_data_arr();

但是然后我会分配一个额外的内存数组,并在所有数组上进行复制,这似乎并不理想。

另一个较少占用内存的选项将是:

struct Test {
    static bool is_init;
    static std::array<unsigned, 123> data;

    Test() {
        if (!is_init) {
            is_init = true;
            data.fill(5);
        }
    }
};

bool Test::is_init = false;
std::array<unsigned, 123> Test::data = {};

但是现在,在构建Test结构时,我有额外的开销。

现在,我知道您可以像这样初始化pod数组:std::array<int, 3> a = {1, 2, 3};但是对于N大型数组,这将很快变得难以维护。

我遇到的每个解决方案都只fill在数组类上使用成员函数,但始终将数组视为非静态成员变量,或者将其初始化为main,这对我的情况没有任何帮助。

编辑:我创建了这个实用程序标头,将第二个选项推广化。#pragma一次

#include <utility>
#include <iterator>
#include <algorithm>
#include <type_traits>

namespace Utils {

    template<typename Container>
    using element_type_t = std::remove_reference_t<decltype(*std::begin(std::declval<Container&>()))>;

    template<class Container>
    static Container create_filled_container(const element_type_t<Container>& value) {
        Container container = {};
        std::fill(container.begin(), container.end(), std::move(value));
        return container;
    }

}

可能可以进一步改善它,但它似乎起作用。用法如下:

std::array<unsigned, 123> Test::data = Utils::create_filled_container<decltype(data)>(456);

将所有元素设置为您指定的任何内容。

Edit2:所以我做了一些更多的测试,它看起来像调用一个函数来填充数组而不是手动执行它并不总是产生相同的程序集。

我在这里设置了一个演示

Edit3:修改了一些东西,因此它可以是constexpr,这是它的当前形式:

template<class Container>
static constexpr Container create_filled_container(const element_type_t<Container>& value) {
    Container container = {};

    for (auto it = container.begin(); it != container.end(); ++it)
        *it = value;

    return container;
}

现在生产相同的组件。

道格

使用constexpr函数或lambda对其进行初始化。没有生成运行时代码。

#include <array>
#include <iostream>

template <unsigned len, unsigned val>
constexpr std::array<unsigned, len> initialize_array()
{
    std::array<unsigned, len> ret{};
    for (int i = 0; i < len; i++)
        ret[i] = val;
    return ret;
}

struct Test {
    constexpr static std::array<unsigned, 123> data{ initialize_array<123,5>() };
};

int main() {
    std::cout << Test::data[4] << "\n";
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在c ++ 11中初始化std :: vector <std :: string>的静态constexpr成员?

C ++静态数据成员初始化

非静态数据成员初始化器仅与-std = c ++ 11或-std = gnu ++ 11一起提供

值初始化std :: array成员?

C++模板类静态成员初始化

C ++静态结构类型成员初始化

Eigen中的C ++静态数据成员初始化错误

调用静态成员的方法以在C ++中进行初始化

在C ++中初始化静态字符串成员

用 lambda 初始化的 C++ 静态成员

初始化存储 lambda 函数的 C++ 静态成员

如何使用std :: array构造函数参数C ++列表初始化const std :: array成员

类C ++的静态函数成员中的静态数据成员的初始化顺序

C++:为 std::vector 分配内存,然后并行初始化其元素

初始化后重新初始化C ++静态成员

具有非静态成员初始化程序的类的C ++ 11聚合初始化

如何才能静态断言std :: array类成员在c ++ 11中进行排序?

C ++类可以在头文件中包含内联初始化的静态const std :: array吗?

C#初始化以lambda为成员的结构

C ++:使用int vs struct静态依赖于静态成员变量的初始化

是否可以在C ++中的类的静态方法中初始化静态成员?

C ++如何从值列表初始化向量成员

静态初始化C ++,未设置值

在C ++类中初始化彼此相等的静态值

使用默认成员初始化程序的std :: array的零初始化元素

在C ++ 11中初始化结构的C ++ std :: array

为什么C ++会用零初始化std :: vector而不初始化std :: array?

将std :: enable_if与离线成员函数和模板化静态成员条件一起使用

c ++:初始化成员结构的静态字段的正确方法