usar leer imprimir funciones ejemplos como caracteres cadenas cadena arreglo c++ parsing stdvector most-vexing-parse

c++ - leer - El constructor vectorial con dos parámetros se analiza como una declaración de función



imprimir cadena de caracteres en c (1)

Sigue siendo el análisis más irritante.

std::vector<std::string> // return type vec( // function name std::istream_iterator<std::string>(iss), // param 1: an iterator called (iss), or just iss std::istream_iterator<std::string>() // param 2: unnamed function ); // returning iterator

geordi dice:

<tomalak> << ETYPE_DESC(vec); std::vector<std::string> vec(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>()); <geordi> lvalue function taking a istream_iterator<string, char, char_traits<char>, long> , a pointer to a nullary function returning a istream_iterator<string, char, char_traits<char>, long> , and returning a vector of strings

El quid de la cuestión, en realidad, es que los nombres de los parámetros pueden tener paréntesis a su alrededor (es decir, iss(iss) ) sin alterar la semántica de la declaración. A veces.

Utilice otro conjunto de paréntesis que también rodeen el tipo , como lo mostró, para forzar que el primer parámetro (y, en consecuencia, el segundo) se analice como una expresión en lugar de una declaración.

Si esto ayuda, también considere:

void foo(int (x)) { cout << x; } int main() { foo(42); }

La salida es 42 .

Considera este ejemplo:

#include <iostream> #include <string> #include <vector> #include <iterator> int main() { std::string sen = "abc def ghi jkl"; std::istringstream iss(sen); std::vector<std::string> // declaration in question vec(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>()); std::copy(vec.begin(), vec.end(), std::ostream_iterator<std::string>(std::cout, "/n")); }

El compilador arroja un error en la llamada a std::copy

request for member ''begin'' in ''vec'', which is of non-class type...

Puedo evitar el error de esta manera:

std::istream_iterator<std::string> it_begin(iss); std::istream_iterator<std::string> it_end; std::vector<std::string> vec(it_begin, it_end);

o poniendo paréntesis alrededor de cada parámetro, como este:

std::vector<std::string> vec((std::istream_iterator<std::string>(iss)), (std::istream_iterator<std::string>()));

o incluso con la nueva inicialización uniforme en C ++ 11:

std::vector<std::string> vec { /*begin*/, /*end*/ };

¿Por qué el compilador analiza la declaración en el ejemplo como una declaración de función? Sé sobre el análisis más irritante, pero pensé que eso solo ocurre con listas de parámetros vacías. También me pregunto por qué funciona la segunda solución.