std :: ignore z powiązaniami strukturalnymi?

87

Preludium:

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

C ++ 1z wprowadzi składnię powiązań strukturalnych, która umożliwi pisanie zamiast

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

coś jak

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

Jednak można std::tierównież określić std::ignoreignorowanie niektórych komponentów, np .:

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

Czy będzie możliwe zrobienie czegoś podobnego przy użyciu nowej składni strukturalnych powiązań? Jak by to działało?

jotik
źródło
2
Po prostu umieść tam dowolną nazwę.
n. zaimki m.
1
@nm czy dowolna nazwa nie utworzy kopii?
Piotr Skotnicki
1
@Piotr Myślę, że nie więcej kopii niż z std::ignore. Ponieważ mamy zagwarantowane wykluczenie kopiowania, zmienna zastępcza jest inicjalizowana; z std::tie, std::ignoreinicjowany jest element tymczasowy znajdujący się w prawej części przypisania do .
j6t
1
Możliwe byłoby posiadanie makra, auto[IGNORE]które generuje unikalną nazwę (np. Z LICZNIKIEM lub LINIĄ specyficzną dla kompilatora ). Byłby wystarczająco czytelny, aw praktyce funkcjonowałby jak std::ignoredla std::tie.
KABoissonneault
2
@PiotrSkotnicki Nie, jedyną kopią, jaką tworzy deklaracja dekompresji, jest to, co jest dekomponowane. Deklarowane rzeczy są aliasami do członków / elementów tej rzeczy lub odwołaniami, które wiążą się z tym, co getzwraca.
TC

Odpowiedzi:

62

Propozycja powiązań strukturalnych zawiera dedykowaną sekcję z odpowiedzią na Twoje pytanie ( P0144R2 ):

3.8 Czy powinien istnieć sposób na jawne ignorowanie składników?

Motywacją byłoby wyciszenie ostrzeżeń kompilatora o nieużywanych nazwach. Uważamy, że odpowiedź powinna brzmieć „jeszcze nie”. Nie jest to motywowane przypadkami użycia (wyciszanie ostrzeżeń kompilatora jest motywacją, ale nie jest przypadkiem użycia jako takim) i najlepiej zostawić to do czasu, gdy będziemy mogli wrócić do tego w kontekście bardziej ogólnej propozycji dopasowania wzorców, gdzie to powinno wypaść jako przypadek specjalny.

Symetria z std::tiesugerowałaby użycie czegoś takiego jak std::ignore:

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

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

Jednak wydaje się to niezręczne.

Przewidywanie dopasowywania wzorców w języku może sugerować użycie symbolu wieloznacznego, takiego jak _lub *, ale ponieważ nie mamy jeszcze dopasowywania wzorców, przedwczesne jest wybieranie składni, o której wiemy, że będzie kompatybilna. Jest to czyste rozszerzenie, które może czekać na uwzględnienie z dopasowywaniem wzorców.

Należy jednak pamiętać, że wersja robocza Standardu jest obecnie aktualizowana przez odpowiednie organy krajowe (NB) i istnieje komentarz NB dotyczący tej funkcji ( P0488R0 , US100):

Deklaracje dekompozycji powinny zapewniać składnię umożliwiającą odrzucenie niektórych zwracanych wartości, podobnie jak std::tieużycie std::ignore.

metalfox
źródło
6
Jest już za późno, ale chciałbym zwrócić uwagę, że funkcja, która wydaje się niewygodna w użyciu i prawdopodobnie zostanie zastąpiona w przyszłości, jest lepsza niż brak możliwości korzystania z tej funkcji w ogóle , a to nie wygląda na rodzaj rzecz, która sprawi, że komisja normalizacyjna zażyczy sobie wehikułu czasu, ponieważ nie ma innej rozsądnej interpretacji std::ignorew strukturalnych wiązaniach.
Daniel H
11

Czy będzie możliwe zrobienie czegoś podobnego przy użyciu nowej składni strukturalnych powiązań?

Nie. Będziesz musiał tylko wymyślić nazwę zmiennej, która nie zostanie wymieniona później.

Nicol Bolas
źródło
25
który wygeneruje ostrzeżenie o nieużywanej zmiennej -Wunused-variable, możesz użyć: [[maybe_unused]] auto [ a, b, dummy ] = std::tuple(1,"2",3f);ale to oznacza, że ​​każda z nich może być nieużywana, nie będziesz wiedział, która. w tej chwili nie ma dobrego rozwiązania w tej sprawie. miejmy nadzieję, że zostanie poprawiony w C ++ 20. pobrane stąd: stackoverflow.com/questions/41404001/…
seryna
3
„w tej chwili nie ma dobrego rozwiązania dla tego przypadku” : to nie do końca prawda: możesz po prostu użyć, (void)dummy;aby pozbyć się ostrzeżenia o nieużywanej zmiennej bez wpływu na inne zmienne.
andreee
16
@andreee: Używanie wyrażenia tylko do uciszenia ostrzeżenia nie jest tym, co nazwałbym „dobrym rozwiązaniem”.
Nicol Bolas
„Użycie instrukcji tylko po to, by uciszyć ostrzeżenie…” Czy kończą się nam instrukcje?
AndyJost
2
@AndyJost: Nie, ale kończy nam się przestrzeń wizualna na ekranie. Wydawanie jej, szczególnie cennej przestrzeni w pionie, na wyciszenie ostrzeżenia nie jest przydatne.
Nicol Bolas