std :: ignore con enlaces estructurados?

83

Preludio:

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

C ++ 1z introducirá sintaxis para enlaces estructurados que permitirán escribir en lugar de

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

algo como

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

Sin embargo, std::tietambién se permite especificar std::ignoreque se ignoren ciertos componentes, por ejemplo:

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

¿Será posible hacer algo similar usando la nueva sintaxis de enlaces estructurados? ¿Cómo funcionaría?

jotik
fuente
2
Solo ponga un nombre arbitrario allí.
n. 'pronombres' m.
1
@nm, ¿un nombre arbitrario no creará una copia?
Piotr Skotnicki
1
@Piotr No más copias que con std::ignore, creo. Como tenemos la elisión de copia garantizada, la variable ficticia se inicializa; con std::tie, std::ignorese inicializa el temporal que está en el lado derecho de la asignación .
j6t
1
Sería posible tener una macro auto[IGNORE]que genere un nombre único (por ejemplo, con COUNTER o LINE específico del compilador ). Sería lo suficientemente legible, y en la práctica funcionaría como std::ignorepara std::tie.
KABoissonneault
2
@PiotrSkotnicki No, la única copia que hace una declaración de descomposición es lo que se está descomponiendo. Las cosas que se declaran son alias a los miembros / elementos de esa cosa o referencias que se unen a lo que getregresa.
TC

Respuestas:

58

La propuesta de enlaces estructurados contiene una sección dedicada que responde a su pregunta ( P0144R2 ):

3.8 ¿Debería haber una forma de ignorar explícitamente los componentes?

La motivación sería silenciar las advertencias del compilador sobre nombres no utilizados. Creemos que la respuesta debería ser "todavía no". Esto no está motivado por casos de uso (silenciar las advertencias del compilador es una motivación, pero no es un caso de uso per se), y es mejor dejarlo hasta que podamos revisar esto en el contexto de una propuesta de coincidencia de patrones más general donde esto debería fallar. como un caso especial.

La simetría con std::tiesugeriría usar algo como std::ignore:

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

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

Sin embargo, esto se siente incómodo.

Anticipar la coincidencia de patrones en el lenguaje podría sugerir un comodín como _o *, pero dado que aún no tenemos la coincidencia de patrones, es prematuro elegir una sintaxis que sepamos que será compatible. Esta es una extensión pura que puede esperar a ser considerada con la coincidencia de patrones.

Sin embargo, tenga en cuenta que el borrador de trabajo de la Norma está siendo revisado actualmente por los Organismos Nacionales relevantes (NB), y hay un comentario de NB que solicita esta característica ( P0488R0 , US100):

Las declaraciones de descomposición deben proporcionar sintaxis para descartar algunos de los valores devueltos, al igual que los std::tieusos std::ignore.

metalfox
fuente
6
Ahora es demasiado tarde, pero me gustaría señalar que una función que se siente incómoda de usar y que probablemente será reemplazada en el futuro es mejor que no tener la capacidad de usar la función en absoluto , y este no parece el tipo de algo que hará que el comité de estándares desee una máquina del tiempo porque no hay otra interpretación razonable de std::ignoreenlaces estructurados.
Daniel H
10

¿Será posible hacer algo similar usando la nueva sintaxis de enlaces estructurados?

No. Solo tendrá que inventar un nombre de variable que no se mencionará más adelante.

Nicol Bolas
fuente
25
que generará una advertencia de variable no utilizada -Wunused-variable, puede usar: [[maybe_unused]] auto [ a, b, dummy ] = std::tuple(1,"2",3f);pero eso significa que cualquiera de ellas puede estar sin usar, no sabrá cuál. no hay una buena solución para ese caso en este momento. con suerte se mejorará en c ++ 20. tomado de aquí: stackoverflow.com/questions/41404001/…
serina
3
"No hay una buena solución para ese caso en este momento" : eso no es del todo cierto: simplemente puede usar (void)dummy;para deshacerse de la advertencia de variable no utilizada sin afectar las otras variables.
andreee
16
@andreee: Usar una declaración solo para silenciar una advertencia no es lo que yo llamaría una "buena solución".
Nicol Bolas
"Usar una declaración sólo para silenciar una advertencia ..." ¿Nos estamos quedando sin declaraciones?
AndyJost
1
@AndyJost: No, pero nos estamos quedando sin espacio visual en la pantalla. Gastarlo, un espacio vertical particularmente valioso, para silenciar una advertencia no es útil.
Nicol Bolas