C++ Weekly - Episode 123 脱水版: Using in_place_t
std::expected, std::optional, std::variant, std::any 构造函数可以通过传递 std::in_place
, std::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…