语法友好的方法来替换初始化列表?

时间:2018-03-24 01:34:35

标签: c++ syntax initializer-list

我现在在我的代码中有一个生成std::vector<SomeHeavyComplexType>的函数(在下面的代码中只是一个int):

inline std::vector<int> generateComplexConf() {
    return {1,2,3,4,5};
}

struct MyComplexStruct {
   const std::vector<int> my_conf;
   MyComplexStruct() : my_conf(generateComplexConf()) {}
};

这很好,但AFAIK初始化列表是const - 所以上面的代码将在generateComplexConf中生成一个std :: vector,然后将其复制到MyComplexStruct的元素中。

更好的选择是:

inline std::vector<int> generateComplexConf() {
    std::vector<int> ret;
    ret.emplace_back(1);
    ret.emplace_back(2);
    ...
    return ret;
}

struct MyComplexStruct {
   const std::vector<int> my_conf;
   MyComplexStruct() : my_conf(std::move(generateComplexConf())) {}
};

现在std :: vector&lt;&gt;刚刚感动。

我的问题是:

  • 上面的2段代码是否有更好的替代方案 - 即有些东西可以生成与MyComplexStruct() : my_conf{1,2,3,4}完全相同但允许配置对象({1,2,3,4,5})的代码与MyComplexStruct

  • 的定义不同的地方
  • 如果没有,在我使用std::move的代码中,这迫使我多次使用emplace_back(在我的实际代码中数百次)。您是否知道具有更好语法的内容 - 即具有非常量的初始化列表?

编辑:

在评论之后,我应该添加一些精确度。为了澄清我的问题,想象一下std::vector<int>而不是std::vector<Test>,其中Test不可复制,不可移动,不可分配,例如:

struct Test {
    int a;

    Test(int x) : a(x) {}
    Test() : a(1) {}
    Test(Test&&) = delete;
    Test(const Test&) = delete;
    Test& operator=(Test&&) = delete;
    Test& operator=(const Test&) = delete;
};

inline std::vector<Test> generateConf() {
    return {Test{1},Test{2}};
}

inline std::vector<Test> generateConfMove() {
    std::vector<Test> r;
    r.emplace_back(1);
    r.emplace_back(2);
    return r;
}

struct MyComplexStruct {
   const std::vector<int> my_conf;
   MyComplexStruct() : my_conf(generateConf()) {}
};

虽然generateConf会尝试使用Test的复制构造函数,generateConfMove会尝试使用Test的移动构造函数(因为有人在评论中相应地更正了我,data初始化列表的列表是const)。

如果我重新提出我的两个问题:

  1. Test不可移动且不可复制的一般情况下,无论如何都要将代码配置在与构造函数不同的位置

  2. 如果Test只是非可复制的,那么emplace_back工作正常。但在这种情况下,是否还有其他更符合语法的&#39;这样做的方法?

1 个答案:

答案 0 :(得分:0)

你的第一次剪裁非常精细 - 无法改进 - 事情从那里开始走下坡路。编译器足够聪明,知道当一个函数按值返回时,该值可以在调用者分配时直接删除和构造,或者 - 失败(它不能保证在C ++之前省略) 17) - 必要时离开。

  

但是允许将代码配置对象({1,2,3,4,5})放在与MyComplexStruct定义不同的地方?

没有比你已经做过的更好的了。如果您未在初始化列表中进行分配,则向量数据成员my_conf将默认构建,然后您必须在以后将值放入其中 - 效率较低。< / p>