Должна ли const иметь структурированную привязку к копии const c-массива? - PullRequest
0 голосов
/ 11 декабря 2018

Рассмотрим этот код ( 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 следует стандарту.С другой стороны, я чувствую, что намерения заключались в том, чтобы поведение для массивов, агрегатов и кортежоподобных типов было эквивалентным.

1 Ответ

0 голосов
/ 11 декабря 2018

Формулировка стандарта в [dcl.struct.bind] гласит:

Если выражение присваивания в инициализаторе имеет тип массива A, а квалификатор ref отсутствует, e имеет тип cv A, и каждый элемент инициализируется копией или напрямую инициализируется изсоответствующий элемент выражения-присваивания , как указано в форме инициализатора .

У нас есть auto [i,j] = ar;, ar имеет тип массива const int[2], и формулировка стандарта проясняет, что e имеет тип const int[2].Таким образом, в соответствии с формулировкой , каждая привязка ссылается на тип элемента - который равен const int.Лягушка технически правильна.

Однако, как указывает Ричард Смит в gcc bug 80649 :

Я думаю, что это ошибка в стандарте.Спецификаторы cv типа массива должны быть отброшены, как и для любого обычного автоматического вывода.

Это кажется правильным.Когда вы пишете auto x = y;, вы наверняка ожидаете, что x не будет верхнего уровня const, но здесь у нас есть ситуация, в которой это все еще есть.Я не думаю, что для этого пока есть проблема с ядром, но она должна быть.

...