-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Full name of submitter (unless configured in github; will be published with the issue): Barry Revzin
Reference (section label): dcl.struct.bind
Link to reflector thread (if any):
Issue description:
In the tuple case of structured bindings, we say:
In either case, e is an lvalue if the type of the entity e is an lvalue reference and an xvalue otherwise. Given the type
Tidesignated bystd::tuple_element<i, E>::typeand the typeUidesignated by eitherTi&orTi&&, whereUiis an lvalue reference if the initializer is an lvalue and an rvalue reference otherwise, variables are introduced with unique names ri as follows:S Ui ri = initializer ;
That is, we're always declaring either lvalue references or rvalue references — and then the initializer is either e.get<i>() or get<i>(e). However, what if get returns a prvalue?
In Kona, we adopted P1789, which adds structured bindings support to std::integer_sequence. Per the wording in the paper, this:
constexpr auto [...Is] = std::make_index_sequence<2>();decomposes into:
constexpr auto e = std::integer_sequence<size_t, 0, 1>();
constexpr size_t&& Is#0 = 0;
constexpr size_t&& Is#1 = 1;This means that the Is... are mutable, which is surprising, undesired, and violates [expr.const]/9.5 anyway.
We could fix this in the library wording — either by removing the const integer_sequence specialization or making the base specialization make the type T const instead of T. Either the way, the result there would be that the Is... would all be constexpr size_t const&& instead, which would work fine.
But it would probably be less surprising to have the prvalue case in structured bindings simply not be references at all, so that the constexpr would properly propagate const-ness.
Suggested resolution:
Something like this:
Given the type
Tidesignated bystd::tuple_element<i, E>::typeand the typeUidesignated byeitherTi&orTi&&, whereUiis an lvalue reference if the initializer is an lvalue and an rvalue reference otherwiseTiif the initializer is a prvalue,Ti&if the initializer is an lvalue, andTi&&otherwise, variables are introduced with unique names ri as follows: