我可以将元素移出 std::initializer_list<T>
吗?
#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)); // kosher?
}
}
由于 std::intializer_list<T>
需要特别注意编译器并且没有像 C++ 标准库的普通容器那样的值语义,所以我宁愿安全也不愿问。
原文由 fredoverflow 发布,翻译遵循 CC BY-SA 4.0 许可协议
不,这不会按预期工作;你仍然会得到副本。我对此感到非常惊讶,因为我认为
initializer_list
的存在是为了保留一系列临时对象,直到它们成为move
‘d。begin
andend
forinitializer_list
returnconst T *
, so the result ofmove
in your code isT const &&
一个不可变的右值引用。这样的表达不能有意义地移开。它将绑定到T const &
类型的函数参数,因为右值确实绑定到 const 左值引用,您仍然会看到复制语义。可能是因为编译器可以选择将
initializer_list
静态初始化常量,但将其类型initializer_list
或const initializer_list
似乎更简洁---
由编译器自行决定,因此用户不知道是否期望const
或来自begin
和end
的可变结果。但这只是我的直觉,可能有一个很好的理由我错了。更新: 我已经为
initializer_list
支持仅移动类型编写 了一个 ISO 提案。这只是初稿,还没有在任何地方实施,但您可以查看它以对问题进行更多分析。