在 C 中,一个初始化器列表,表示为 std::initializer_list
在下面的代码片段中,函数 foo 接受一个初始化列表作为参数:
#include <initializer_list> #include <utility> template<typename T> void foo(std::initializer_list<T> list) { for (auto it = list.begin(); it != list.end(); ++it) { bar(std::move(*it)); // Intended to move the element } }
出现这个问题是因为 std::initializer_list
不幸的是,无缝元素移动的期望是没有根据的。尝试从初始值设定项列表中移动元素将产生意外结果。不是重新定位元素,而是创建副本。此行为源于 std::initializer_list
因此,bar(std::move(*it)) 中使用的移动表达式绑定到 T 类型的函数参数const &,有效地保留了副本。
此限制的原因归因于编译器实例化的特权std::initializer_list 作为静态初始化常量。允许从开始到结束的可变结果会阻碍这种优化,从而在编译器的设计中引入复杂性。
尽管出现了意外的行为,但解决方案可能即将出现。 [ISO 提案](https://github.com/CaseyCarter/iso-changes/blob/master/icpp/p1716r4.md) 旨在引入对仅移动类型的初始值设定项列表支持。这项工作旨在增强语言的功能,并提供更一致的方法来处理初始化列表和移动语义。
以上是我们可以安全地从 C 中的 `std::initializer_list` 中移动元素吗?的详细内容。更多信息请关注PHP中文网其他相关文章!