In C , an initializer list, denoted as std::initializer_list
In the code snippet below, a function foo accepts an initializer list as an argument:
#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 } }
The concern arises because std::initializer_list
Unfortunately, the expectation of seamless element movement is unfounded. An attempt to move elements from an initializer list will yield unexpected results. Instead of relocating the elements, copies are created. This behavior stems from the fact that the begin and end functions in std::initializer_list
Consequently, the move expression employed in bar(std::move(*it)) binds to a function parameter of type T const &, effectively preserving the copies.
The reason for this limitation is attributed to the compiler's prerogative to instantiate std::initializer_list as a statically initialized constant. Allowing mutable results from begin and end would hinder this optimization, introducing complexity in the compiler's design.
Despite the unexpected behavior, a solution may lie on the horizon. An [ISO proposal](https://github.com/CaseyCarter/iso-changes/blob/master/icpp/p1716r4.md) seeks to introduce initializer list support for move-only types. This effort aims to enhance the language's capabilities and provide a more consistent approach to working with initializer lists and move semantics.
The above is the detailed content of Can We Safely Move Elements from a `std::initializer_list` in C ?. For more information, please follow other related articles on the PHP Chinese website!