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);
}
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.