Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why C++ structured bindings don't work with initializer lists?

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 ?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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 E to denote the type of the expression e. (In other words, E is the equivalent of std::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 E is an array type, then the names are bound to the array elements.

Case 2: if E is a non-union class type and std::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 E is a non-union class type but std::tuple_size<E> is not a complete type, then the names are bound to the accessible data members of E.

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading