Un detalle confuso sobre el análisis más desconcertante

4 minutos de lectura

avatar de usuario
templatetypedef

Mi pregunta es cómo se puede analizar la siguiente línea como una declaración de función:

vector<int> v(istream_iterator<int>(cin), istream_iterator<int>());

Entiendo la mayoría de los detalles de Most Vexing Parse y por qué el segundo iterador temporal puede interpretarse como un tipo que es una función que devuelve un iterador y no toma argumentos, pero lo que no entiendo es por qué el primer iterador temporal puede ser interpretado como un tipo. ¿Qué tipo representa? Mi idea es que sería algún tipo de función, pero no puedo ver cómo el nombre cin se acostumbra ¿Está declarando que el parámetro es un istream_iterator<int> llamado cin? Si es así, ¿eso significa que puede poner entre paréntesis arbitrariamente los nombres de los argumentos de las funciones? Y si es así, ¿por qué?

¿Ya dije que me gustaba Clang (mucho)?

Simplemente intente lo siguiente (código simplificado)

#include <vector>

void foo(std::vector<int>);

int main() {
  std::vector<int> v(int(i), int());
  foo(v);
}

En el recién renovado Prueba LLVM (bueno, simplemente pasó de llvm-gcc a clang).

Y obtienes:

/tmp/webcompile/_21483_0.cc:6:21: warning: parentheses were disambiguated
                                           as a function declarator
  std::vector<int> v(int(i), int());
                    ^~~~~~~~~~~~~~~
/tmp/webcompile/_21483_0.cc:7:3: error: no matching function for call to 'foo'
  foo(v);
  ^~~
/tmp/webcompile/_21483_0.cc:3:6: note: candidate function not viable:
     no known conversion from 'std::vector<int> (int, int (*)())'
     to 'std::vector<int>' for 1st argument
void foo(std::vector<int>);
     ^
3 diagnostics generated.

Y por lo tanto, @john tiene razón, int(i) se interpreta como int ies decir, un parámetro con nombre para la función.

  • Es como un parámetro de una función.

    – Bo Person

    10 de agosto de 2011 a las 8:36

  • Creo que están en el contexto de la pregunta formulada (quizás no debería haber dicho exactamente). ¿Cuidado para elaborar?

    – Juan

    10 de agosto de 2011 a las 8:37

  • @Nawaz: istream_iterator<int>(cin) no se interpreta como una expresión sino como una declaración de parámetros, ese es el punto de la pregunta.

    – Juan

    10 de agosto de 2011 a las 8:48

  • @Nawaz, lo entendiste mal. no dije istream_iterator<int>(cin) estaba causando el problema. El OP preguntó específicamente cómo istream_iterator<int>(cin) podría interpretarse como una declaración de parámetros. Así que esa es la pregunta que respondí.

    – Juan

    10 de agosto de 2011 a las 9:47

  • @Nawaz, no se necesita contexto. Siempre es la declaración de cinno puede ser un objeto temporal. te has equivocado.

    – Johannes Schaub – litb

    10 de agosto de 2011 a las 15:39


Sí, es el nombre del parámetro. Y sí, puede agregar un conjunto de paréntesis, porque a veces es necesario.

Si el parámetro es un puntero de función, void (*f)() tienes que escribirlo así.

Las personas que escriben el estándar no han dedicado su valioso tiempo a señalar exactamente los casos en los que los paréntesis están permitidos o en los que realmente se requieren, por lo que el estándar simplemente dice que usted puede tenerlos.

  • ¿Puede dar un ejemplo si esto sería necesario?

    – templatetypedef

    10 de agosto de 2011 a las 8:28

  • int *a[10] es una matriz de 10 punteros int, pero int (*a)[10] es un puntero a una matriz de 10 enteros (espero haberlo entendido bien).

    – Juan

    10 de agosto de 2011 a las 8:32

  • Ah, entonces no es tanto “lo necesitas” como “algunos tipos lo requieren”. Malinterpreté su comentario como “hay tipos para los que es un error de tiempo de compilación no incluir un conjunto adicional de paréntesis que de otro modo no sería necesario”.

    – templatetypedef

    10 de agosto de 2011 a las 8:34

  • ¿Puede dar un ejemplo si esto sería necesario?

    – templatetypedef

    10 de agosto de 2011 a las 8:28

  • int *a[10] es una matriz de 10 punteros int, pero int (*a)[10] es un puntero a una matriz de 10 enteros (espero haberlo entendido bien).

    – Juan

    10 de agosto de 2011 a las 8:32

  • Ah, entonces no es tanto “lo necesitas” como “algunos tipos lo requieren”. Malinterpreté su comentario como “hay tipos para los que es un error de tiempo de compilación no incluir un conjunto adicional de paréntesis que de otro modo no sería necesario”.

    – templatetypedef

    10 de agosto de 2011 a las 8:34

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad