initializer_list and move semantics(initializer_list 和移动语义)
问题描述
我可以将元素移出 std::initializer_list
Am I allowed to move elements out of a 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++ 标准库的普通容器那样具有值语义,我宁愿安全而不是抱歉和询问.>
Since std::intializer_list<T> requires special compiler attention and does not have value semantics like normal containers of the C++ standard library, I'd rather be safe than sorry and ask.
推荐答案
不,这不会按预期工作;你仍然会得到副本.我对此感到非常惊讶,因为我认为 initializer_list 的存在是为了保留一个临时数组,直到它们被 move 'd.
No, that won't work as intended; you will still get copies. I'm pretty surprised by this, as I'd thought that initializer_list existed to keep an array of temporaries until they were move'd.
begin 和 end for initializer_list 返回 const T *,所以 move 在您的代码中是 T const && — 一个不可变的右值引用.这样的表达不能有意义地移开.它将绑定到 T const & 类型的函数参数,因为右值确实绑定到 const 左值引用,并且您仍然会看到复制语义.
begin and end for initializer_list return const T *, so the result of move in your code is T const && — an immutable rvalue reference. Such an expression can't meaningfully be moved from. It will bind to an function parameter of type T const & because rvalues do bind to const lvalue references, and you will still see copy semantics.
可能的原因是编译器可以选择使 initializer_list 成为静态初始化的常量,但将其类型设为 initializer_list 似乎更清晰或 const initializer_list 由编译器自行决定,因此用户不知道是否期望 const 或 begin 和 的可变结果结束.但这只是我的直觉,可能有一个很好的理由我错了.
Probably the reason for this is so the compiler can elect to make the initializer_list a statically-initialized constant, but it seems it would be cleaner to make its type initializer_list or const initializer_list at the compiler's discretion, so the user doesn't know whether to expect a const or mutable result from begin and end. But that's just my gut feeling, probably there's a good reason I'm wrong.
更新:我写了 ISO 提案,用于initializer_list 支持仅移动类型.这只是一个初稿,还没有在任何地方实施,但您可以查看它以进一步分析问题.
Update: I've written an ISO proposal for initializer_list support of move-only types. It's only a first draft, and it's not implemented anywhere yet, but you can see it for more analysis of the problem.
这篇关于initializer_list 和移动语义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:initializer_list 和移动语义
- 从父 CMakeLists.txt 覆盖 CMake 中的默认选项(...)值 2021-01-01
- 使用 __stdcall & 调用 DLLVS2013 中的 GetProcAddress() 2021-01-01
- 将 hdc 内容复制到位图 2022-09-04
- 如何提取 __VA_ARGS__? 2022-01-01
- OpenGL 对象的 RAII 包装器 2021-01-01
- XML Schema 到 C++ 类 2022-01-01
- 将函数的返回值分配给引用 C++? 2022-01-01
- DoEvents 等效于 C++? 2021-01-01
- GDB 不显示函数名 2022-01-01
- 哪个更快:if (bool) 或 if(int)? 2022-01-01
