Рассмотрим этот код ( demo ):
#include <tuple>
#include <type_traits>
struct Ag{int i;int j;};
using T = std::tuple<int,int>;
using Ar = int[2];
const Ag ag {};
const T t {};
const Ar ar {};
void bind_ag(){
auto [i,j] = ag;
static_assert(std::is_same_v<decltype((i)),int&>);
}
void bind_t(){
auto [i,j] = t;
static_assert(std::is_same_v<decltype((i)),int&>);
}
void bind_ar(){
auto [i,j] = ar;
static_assert(std::is_same_v<decltype((i)),int&>); //For GCC
static_assert(std::is_same_v<decltype((i)),const int&>); //For Clang (and standard?)
}
A структурированная привязка к копии const
c-массива объявляется const от Clang и non-const от GCC.
Поведение GCC для c-массива согласуется с поведением, наблюдаемым для агрегатных или кортежоподобных типов.
С другой стороны, из моего прочтения стандарта, я полагаю, Clang следует тому, что написано.В [dcl.struct.bind] / 1 e имеет тип cv A , где A - тип выражения инициализатора, а cv - квалификатор cv.декларации структурированного связывания.И тип выражения инициализатора ar
соответствует [expr.type] / 1 const int[2]
.
Чего следует ожидать?Мое мнение таково, что Clang следует стандарту.С другой стороны, я чувствую, что намерения заключались в том, чтобы поведение для массивов, агрегатов и кортежоподобных типов было эквивалентным.