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

87

Прелюдия:

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();

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

Jotik
источник
2
Просто введите произвольное имя.
п. 'местоимения' м.
1
@nm не будет ли произвольное имя создать копию?
Петр Скотницки
1
@Piotr Не больше копий, чем с std::ignore, я думаю. Поскольку мы гарантируем исключение копирования, фиктивная переменная инициализируется; с std::tie, то временное, которое находится справа от присвоения, std::ignoreинициализируется.
j6t
1
Можно было бы иметь макрос, auto[IGNORE]который генерирует уникальное имя (например, со специфичным для компилятора COUNTER или LINE ). Он был бы достаточно читабельным и на практике работал бы как std::ignoreдля std::tie.
KABoissonneault
2
@PiotrSkotnicki Нет, единственная копия, которую делает объявление декомпозиции, - это то, что разлагается. Объявляемые вещи являются либо псевдонимами членов / элементов этой вещи, либо ссылками, которые связываются с тем, что getвозвращается.
TC

Ответы:

62

Предложение структурированных привязок содержит специальный раздел, отвечающий на ваш вопрос ( 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.

Metalfox
источник
6
Сейчас уже слишком поздно, но я хотел бы отметить, что функция, которую неудобно использовать и которая, вероятно, будет заменена в будущем, лучше, чем отсутствие возможности использовать эту функцию вообще , и это не похоже на то, что заставит комитет по стандартам пожелать машину времени, потому что std::ignoreв структурированных привязках нет другой разумной интерпретации .
Daniel H
11

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

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

Никол Болас
источник
25
который будет генерировать предупреждение о неиспользуемых переменных -Wunused-variable, вы можете использовать: [[maybe_unused]] auto [ a, b, dummy ] = std::tuple(1,"2",3f);но это означает, что любой из них может быть неиспользованным, вы не узнаете, какой из них. для этого случая сейчас нет хорошего решения. Надеюсь, это будет улучшено в C ++ 20. взято отсюда: stackoverflow.com/questions/41404001/…
серин
3
«сейчас нет хорошего решения для этого случая» : это не совсем так: вы можете просто использовать, (void)dummy;чтобы избавиться от предупреждения о неиспользуемой переменной, не затрагивая другие переменные.
andreee
16
@andreee: Использование оператора только для подавления предупреждения - это не то, что я бы назвал «хорошим решением».
Никол Болас
«Использование утверждения только для того, чтобы заглушить предупреждение…» У нас заканчиваются утверждения?
AndyJost
2
@AndyJost: Нет, но у нас заканчивается визуальное пространство на экране. Тратить это, особенно драгоценное вертикальное пространство, на подавление предупреждений бесполезно.
Никол Болас