C++ Weekly - Episode 123 脱水版: Using in_place_t

33 阅读1分钟

C++ Weekly - Episode 123 脱水版: Using in_place_t

std::expected, std::optionalstd::variantstd::any 构造函数可以通过传递 std::in_placestd::in_place_type, and std::in_place_index 来指定包装对象的原地构造。

std::optional, std::any 在初始化时,默认构造并不会实例化模板类型, 也就是不会调用模板对象的构造函数。

假如我们需要初始化所包装的模板对象,我们一般可以通过传递拷贝/移动一个已有/临时对象。比如:

    // 移动
    std::vector<int> vec(10, 3);
    std::optional<std::vector<int>> o(std::move(vec));
    
    // 临时对象
    std::optional<std::vector<int>> o2(std::vector<int>(10, 3));

但是上述两种方法均会产生了多余的临时对象,相对来说,效率不高。std::in_place 提供了一个原地构造的方法, 可以避免临时对象的产生。此时,模板对象的构造函数将被调用。

    // std::in_place
    std::optional<std::vector<int>> o3(std::in_place, 10, 3);

当然,任何可以构造模板对象的构造参数都可以被传递,例如类似初始化器:

    std::optional<std::vector<int>> o4(std::in_place, {1, 2, 3, 4, 5});

类似地,std::in_place_type 可以指定需要构造对象的类型,例如:

    std::any a(std::in_place_type_t<std::vector<int>>{}, 10, 3);
Note:

使用场景或者优势

  • 需要初始化时构造模板对象实例;
  • 非无参的构造函数需要接受多个参数;
  • 避免移动或者拷贝而产生多余的临时对象;
  • 对于不可拷贝或者移动的模板对象,例如 std::mutex 构造。

这里有一篇文章提供了很好的参考:blog.csdn.net/yihuajack/a…

Reference: