How to use the vector range constructor correctly?

I want to load all lines from a text file into vector<string using its range constructor, and then output them via cout :

 #include<iostream> #include<fstream> #include<vector> #include<iterator> using namespace std; int main() { ifstream file("file.txt"); vector<string> strings(istream_iterator<string>(file) , istream_iterator<string>()); for(auto s : strings) cout << s << endl; return 0; } 

When I try to compile the above code, I get several errors, for example:

 error: no matching function for call to 'begin(std::vector<std::basic_string<char> > (&) (std::istream_iterator<std::basic_string<char> >, std::istream_iterator<std::basic_string<char> > (*) ()))' for(auto s : strings) ^ 

and several others ...

I think I am missing something obvious here, can anyone help?

+6
source share
1 answer

You are a victim of Vexing Parse itself, where the compiler sees your declaration as a strings function, returning a vector<string> , taking two arguments:

  • a istream_iterator<string> is called file
  • unnamed function pointer without arguments and returning istream_iterator<string> .

To eliminate annoying parsing, use an extra pair of parentheses around the first argument:

 vector<string> strings((istream_iterator<string>(file)) , istream_iterator<string>()); // ^ ^ 

or alternatively in C ++ 11, use curly braces for the strings constructor

 vector<string> strings{istream_iterator<string>(file) , istream_iterator<string>()}; // ^ ^ 

NOTE : Clang warns you about this via -Wvexing-parse (default).

+6
source

Source: https://habr.com/ru/post/970514/


All Articles