【问题标题】:What is the proper way to initialize const containers with different values?用不同的值初始化 const 容器的正确方法是什么?
【发布时间】:2016-08-16 12:29:08
【问题描述】:

我有一些容器struct,其中包含一组配置元素。

struct config
{
    const std::vector<int> config_items;
    const std::vector<double> another_items;
}

另外,我有一个“容器容器”,它应该包含这些配置容器的已知且有限数量的实例(例如 3 个)。每个config 实例在对应的vectors 中应该有不同的ints 和doubles。

struct setup
{
    const std::vector<config> items;
}

所有vectors 的项目都应该是const,因为它们应该被定义一次并且永远不会改变。

由于vectors 是const,我只能在构造函数初始化列表中初始化它们。但我希望有多个具有不同值的实例。

我可以创建一些子 structs 来创建子构造函数中的每个配置。但这不起作用,因为我无法在子构造函数中初始化父成员:

struct config_1 : public config
{
    config_1() : config_items { 1, 2 }, another_items { 1.0, 2.0 } {} // Doesn't work
}

这似乎也是一个非常糟糕的决定(删除const,复制...):

struct config
{
    std::vector<int> config_items;    
    std::vector<double> another_items;    
}

struct setup
{
    std::vector<config> items;
}

void init()
{
    config c;
    c.config_items = { 1, 2 };
    c.another_items = { 1.0, 2.0 };

    setup s;
    s.items = { c };
}

我也不能创建一个初始化列表构造函数,因为我有多个vectors:

struct config
{
    config(std::initializer_list<int> i, std::initializer_list<double> d); // No go
    std::vector<int> config_items;    
    std::vector<double> another_items;    
}

背景:我想为我的嵌入式应用程序提供一个硬编码的const 配置结构(可能放在数据部分甚至闪存中)。无需从任何配置文件等中读取内容。

所以我的问题是:你会建议我如何创建这样一个const 配置容器?


编辑

std::vectors 在这里实际上是错误的。我正在使用一个自定义容器来保存实例中的数据,例如 std::array,而不是像 std::vector 那样在堆上分配存储空间。

所以环境应该是这样的:

struct config
{
    const std::array<int, 2> config_items;
    const std::array<double, 2> another_items;
}

struct setup
{
    const std::array<config, 3> items;
}

【问题讨论】:

  • [FYI] 向量是动态的,因此需要在运行时进行初始化。如果你想要静态数据,那么你应该考虑使用std::array
  • @NathanOliver,感谢您的建议。 vectors 在这里只是为了简单起见,我们使用的是我们自己的模板化容器和内部数据存储。

标签: c++ c++11 initialization constants


【解决方案1】:

也许只是使用这样的结构?

struct config
{
    const std::vector<int> _a;
    config(const std::vector<int> &a): _a(a) {}
};

稍后在代码中的某处:

config c1({1, 2, 3});
config c2({3, 4, 5, 6});

好的,我们来获取完整的样本:

    struct config
    {
        const std::vector<int> _items;
        config(const std::vector<int> &items): _items(items) {}
    };
    std::vector<config> settings;
    settings.emplace_back(config({1, 2}));
    settings.emplace_back(config({3, 4}));

【讨论】:

    【解决方案2】:

    你可以这样做:

    struct config
    {
        const std::vector<int> config_items = []{
            std::vector<int> retval;
            //put whatever stuff you want in retval
            return retval;
        }();
    }
    

    优化编译器应该优化 lambda 并只将适当的值放入向量中,具体取决于您制作的复杂程度和调用的函数数量,但您可能应该仔细检查。

    请注意,std::vector 将使用堆内存,因此数据永远不会进入闪存(除了极其激进的编译器会变魔术),因此您可能需要std::array

    【讨论】:

    • 我没明白:如何创建 3 个 config 实例,分别持有不同的 config_items
    • @dymanoid 您需要返回一个配置而不仅仅是向量。您是否考虑过使用包含非const vectors 的const config
    【解决方案3】:

    经过一番研究,我决定回答我自己的问题。

    正如 NathanOlivernwp 提到的,所使用的 std::vectors 在堆上分配内存。实际上,我正在使用一个类似于 std::array 的自定义容器,它将数据保存在实例本身中。

    所以我应该在问题中写下这样的内容:

    struct config
    {
        const std::array<int, 2> config_items;
        const std::array<double, 2> another_items;
    }
    
    struct setup
    {
        const std::array<config, 3> items;
    }
    

    现在,由于这些structs 是PODs,我可以使用其中的aggregate initialization

    setup instance
    {
        // std::array c++11-ish double-braces aggregate initialization
        // this is the items member
        { {
            {
                // this is the config_items member
                { { 1, 2 } },
    
                // this is the another_items member
                { { 1.0, 2.0 } },
            },
    
            {
                { { 3, 4 } },
                { { 3.0, 4.0 } },
            },
    
            {
                { { 5, 6 } },
                { { 5.0, 6.0 } },
            }
        } }
    };
    

    现在,我有一个初始化的 instance 结构,其成员是 const,并且没有运行时代码来进行初始化(没有 ctor,没有方法调用),而是原始数据将直接存储在DATA 部分(默认情况下)。这正是我所需要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-24
      • 1970-01-01
      • 1970-01-01
      • 2017-10-03
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多