Информация об изменениях

Сообщение Re: Structured bindings и decltype от 20.12.2024 10:19

Изменено 20.12.2024 10:21 Кодт

Re: Structured bindings и decltype
Здравствуйте, rg45, Вы писали:

R>Доброго времени суток!


R>Возникла у меня непонятка при попытке использовать decltype с элементами structured bindings.


Есть некое деревенское объяснение для понимания, как структурные биндинги работают.
Это не ссылки, а синтаксический сахар к полям структуры.
Слово auto (с const и &) относится к анонимной переменной этой структуры, — со всеми правилами копирования и продления жизни.

Ну а decl type поля — соответствует тому, как это поле объявлено.
Мы же не удивляемся, что
    int x;
    static_assert(std::is_same_v<decltype( x          ), int  >);  // тип объявления x - это int
    static_assert(std::is_same_v<decltype( (x)        ), int& >);  // хотя в любых выражениях, включая тривиальные, x доступен по ссылке

    struct S { int y; int& z; } s {.z = x};

    static_assert(std::is_same_v<decltype( s.y        ), int  >);  // поле объявлено как int
    static_assert(std::is_same_v<decltype( s.z        ), int& >);  // поле объявлено как int&

    static_assert(std::is_same_v<decltype( (s.y)      ), int& >);  // выражение (в скобках)
    static_assert(std::is_same_v<decltype( (s).y      ), int  >);  // поле результата выражения - это всё ещё поле
    static_assert(std::is_same_v<decltype( (&s)->y    ), int  >);  // поле результата выражения (разыменования по стрелке) - опять поле
    static_assert(std::is_same_v<decltype( s.*(&S::y) ), int& >);  // а вот разыменование указателя на член - это выражение


Кстати, лайфхак со скобками — decltype((name)) vs decltype(name). Пользуйтесь
Re: Structured bindings и decltype
Здравствуйте, rg45, Вы писали:

R>Доброго времени суток!


R>Возникла у меня непонятка при попытке использовать decltype с элементами structured bindings.


Есть некое деревенское объяснение для понимания, как структурные биндинги работают.
Это не ссылки, а синтаксический сахар к полям структуры.
Слово auto (с const и &) относится к анонимной переменной этой структуры, — со всеми правилами копирования и продления жизни.

Ну а decl type поля — соответствует тому, как это поле объявлено.
Мы же не удивляемся, что
    int x;
    static_assert(std::is_same_v<decltype( x          ), int  >);  // тип объявления x - это int
    static_assert(std::is_same_v<decltype( (x)        ), int& >);  // хотя в любых выражениях, включая тривиальные, x доступен по ссылке

    struct S { int y; int& z; } s {.z = x};

    static_assert(std::is_same_v<decltype( s.y        ), int  >);  // поле объявлено как int
    static_assert(std::is_same_v<decltype( s.z        ), int& >);  // поле объявлено как int&

    static_assert(std::is_same_v<decltype( (s.y)      ), int& >);  // выражение (в скобках)
    static_assert(std::is_same_v<decltype( (s).y      ), int  >);  // поле результата выражения - это всё ещё поле
    static_assert(std::is_same_v<decltype( (&s)->y    ), int  >);  // поле результата выражения (разыменования по стрелке) - опять поле
    static_assert(std::is_same_v<decltype( s.*(&S::y) ), int& >);  // а вот разыменование указателя на член - это выражение

https://gcc.godbolt.org/z/7KG4WaGes

Кстати, лайфхак со скобками — decltype((name)) vs decltype(name). Пользуйтесь