我可以将元素移出 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++ 标准库的普通容器那样具有值语义,我宁愿安全也不愿抱歉和询问。
最佳答案
不,这不会按预期工作;你仍然会得到拷贝。我对此感到非常惊讶,因为我认为 initializer_list
的存在是为了保留临时数组,直到它们被 move
。
initializer_list
的begin
和end
返回const T *
,所以move< 的结果
在您的代码中是 T const &&
— 一个不可变的右值引用。不能有意义地 move 这样的表达式。它将绑定(bind)到 T const &
类型的函数参数,因为右值确实绑定(bind)到 const 左值引用,并且您仍然会看到复制语义。
可能的原因是编译器可以选择使 initializer_list
成为静态初始化的常量,但似乎将其类型设为 initializer_list
会更清晰或 const initializer_list
由编译器自行决定,因此用户不知道是否期望 const
或 begin
和 的可变结果结束
。但这只是我的直觉,我的错可能有充分的理由。
更新:我写了an ISO proposal initializer_list
支持只 move 类型。这只是初稿,尚未在任何地方实现,但您可以查看它以进一步分析问题。
关于c++ - initializer_list 和 move 语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13880754/