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?


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.


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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.