Why the
#include <initializer_list>
int main() {
auto [a, b] = { 1, 2 };
}
doesn’t compile with the error message:
error: cannot decompose inaccessible member 'std::initializer_list<int>::_M_array' of 'std::initializer_list<int>'
Demo ?
While the code
#include <utility>
int main() {
auto [a, b] = std::make_pair(1, 2);
}
compiles and works just fine?
What is so specific with initializer list that makes its members inaccessible?
Is it any kind of assumption that initializer list creates an object (of a class) with private fields (or even "inaccessible internal structure") or there is something else comes to play?
>Solution :
Structured binding work with arrays or tuple-like types. From cppreference:
We use
Eto denote the type of the expressione. (In other words,Eis the equivalent ofstd::remove_reference_t<decltype((e))>.)A structured binding declaration then performs the binding in one of three possible ways, depending on
E:Case 1: if
Eis an array type, then the names are bound to the array elements.Case 2: if
Eis a non-union class type andstd::tuple_size<E>is a complete type with a member named value (regardless of the type or accessibility of such member), then the "tuple-like" binding protocol is used.Case 3: if
Eis a non-union class type butstd::tuple_size<E>is not a complete type, then the names are bound to the accessible data members ofE.
std::initializer_list is neither an array, nor tuple-like, nor does it have any accessible members.
What is so specific with initializer list that makes its members inaccessible?
It simply doesnt grant you direct access to the underlying array. Its a private member. std::pair on the other hand is tuple-like and its first and second can be accessed via std::tuple_element.
As far as I know there isnt even a std::initializer_list in auto [a, b] = { 1, 2 }; and the error message is somewhat misleading. {1,2} can be used for list initialization and there are some cases where it leads to construction of a std::initializer_list but this isnt one of this cases. For details I refer you to https://en.cppreference.com/w/cpp/language/list_initialization.