Move Semantics and initializer_list
In C , an initializer_list is a temporary sequence of values of type T. It is commonly used to initialize arrays and other containers. However, a question arises: can elements be moved out of an initializer_list?
Consider the following code snippet:
#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)); // Allowable?
}
}
Copy after login
Answer:
Unfortunately, moving elements out of an initializer_list will not behave as intended. It will still result in copies, despite the expectation that initializer_list would hold an array of temporaries until they are moved.
This deviation stems from the fact that initializer_list::begin() and initializer_list::end() return const T *. The result of move in the provided code yields a T const & &&, which represents an immutable rvalue reference. Such an expression cannot be moved from. It binds to a function parameter of type T const & because rvalues bind to const lvalue references, leading to the preservation of copy semantics.
The reason behind this limitation may be to allow the compiler to initialize the initializer_list statically. However, this approach could be refined by allowing the compiler to define the type as initializer_list or const initializer_list, thus eliminating the ambiguity for the user regarding the const or mutable nature of the begin() and end() results.
Nevertheless, a proposed extension to the C standard has been put forth to address this limitation and allow initializer_list to support move-only types. While it is still in its early stages of development, it suggests further exploration and adoption of this feature in the future.
The above is the detailed content of Can Elements Be Moved from a C `initializer_list`?. For more information, please follow other related articles on the PHP Chinese website!