std::ignore со структурированными привязками?

Прелюдия:

std::tuple<int, int, int> f();
std::tuple<int, int, float, int> g();

C++ 1z введет синтаксис для структурированных привязок, который позволит писать вместо

int a, b, c;
std::tie(a, b, c) = f();

что-то вроде

auto [a, b, c] = f();

Тем не мение, std::tie также разрешено указывать std::ignore игнорировать определенные компоненты, например:

std::tie(a, b, std::ignore, c) = g();

Будет ли возможно сделать что-то подобное, используя новый синтаксис структурированных привязок? Как это будет работать?

5 ответов

Решение

Предложение по структурированным привязкам содержит специальный раздел, отвечающий на ваш вопрос ( P0144R2):

3.8 Должен ли быть способ явно игнорировать компоненты?

Мотивация - заставить замолчать предупреждения компилятора о неиспользуемых именах. Мы думаем, что ответ должен быть "еще нет". Это не мотивировано вариантами использования (глушение предупреждений компилятора является мотивацией, но это не случай использования как таковой), и лучше оставить его, пока мы не вернемся к этому в контексте более общее предложение по сопоставлению с образцом, где это должно выпадать как особый случай.

Симметрия с std::tie предложил бы использовать что-то вроде std::ignore:

tuple<T1,T2,T3> f();

auto [x, std::ignore, z] = f(); // NOT proposed: ignore second element

Тем не менее, это чувствует себя неловко.

Предвидение сопоставления с шаблоном в языке может означать подстановочный знак _ или же *, но так как у нас пока нет сопоставления с образцом, преждевременно выбирать синтаксис, который, как мы знаем, будет совместимым. Это чистое расширение, которое может подождать рассмотрения с сопоставлением с образцом.

Однако обратите внимание, что рабочий проект стандарта в настоящее время пересматривается соответствующими национальными органами (NB), и есть комментарий NB, запрашивающий эту функцию ( P0488R0, US100):

Объявления декомпозиции должны обеспечивать синтаксис для отбрасывания некоторых возвращаемых значений, так же как std::tie использования std::ignore,

Будет ли возможно сделать что-то подобное, используя новый синтаксис структурированных привязок?

Нет. Вам просто нужно составить имя переменной, которая не будет упомянута позже.

В C++26 появится красивый заполнитель без имени (P2169R0) . Благодаря этой новой языковой функции наконец-то можно использовать_как способ игнорировать переменные в выражении структурированной привязки. Подробную информацию о конструкции смотрите в связанном документе.

я обычно использую _который является допустимым идентификатором в C++, но выглядит так же, как, например, оператор подчеркивания Kotlin, который отбрасывает лямбда-параметры. В итоге вы получите хороший код, подобный этому

      map([&](auto it) {
    auto [_, deviceServiceXAddr] = it;
    return deviceServiceXAddr;
});

Вот быстрый и грязный хак, но он будет работать только для одного подчеркивания в строке. (Использование source_location в C++20 может распространить его и на столбцы...):

      #define __CONCAT(x,y) x ## y
#define _CONCAT(x,y) __CONCAT(x,y)
#define _ _CONCAT(__tmp_ignore_var_, __LINE__)

int main(int argc, char* argv[])
{
    auto p = make_pair(2,"hello");
    auto [_, b] = p;
    auto [a, _] = p;
    return 0;
}
Другие вопросы по тегам