7

I understand that the following code (from here) is used to read the contents of a file to string:

#include <fstream>
#include <string>

  std::ifstream ifs("myfile.txt");
  std::string content( (std::istreambuf_iterator<char>(ifs) ),
                       (std::istreambuf_iterator<char>()    ) );

However, I don't understand why such seemingly redundant parentheticals are required. For example, the following code does not compile:

#include <fstream>
#include <string>

  std::ifstream ifs("myfile.txt");
  std::string content(std::istreambuf_iterator<char>(ifs),
                      std::istreambuf_iterator<char>()    );

Why are so many parentheses are needed for this to compile?

Community
  • 1
  • 1
Ocasta Eshu
  • 821
  • 3
  • 11
  • 23
  • 6
    The second one is a function declaration. [Most Vexing Parse](http://en.wikipedia.org/wiki/Most_vexing_parse) – chris Sep 25 '12 at 19:50
  • 5
    To prevent [the most vexing parse](http://stackoverflow.com/questions/1424510/most-vexing-parse-why-doesnt-a-a-work). – jrok Sep 25 '12 at 19:51

1 Answers1

12

Because without the parentheses, the compiler treats it as a function declaration, declaring a function named content that returns a std::string and takes as arguments a std::istreambuf_iterator<char> named ifs and a nameless parameter that is a function taking no arguments that returns a std::istreambuf_iterator<char>.

You can either live with the parens, or as Alexandre notes in the comments, you can use the uniform initialisation feature of C++ which has no such ambiguities:

std::string content { std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>() };

Or as Loki mentions:

std::string content = std::string(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());
Seth Carnegie
  • 70,115
  • 19
  • 169
  • 239
  • 3
    Note: In C++11 you can do `std::string content{std::istreambuf_iterator(ifs), std::istreambuf_iterator()};` – Alexandre C. Sep 25 '12 at 19:52
  • 3
    Or you can use: `std::string content = std::string( std::istreambuf_iterator(ifs), std::istreambuf_iterator());` – Martin York Sep 25 '12 at 20:36
  • Or even ``auto content = std::string(std::istreambuf_iterator(ifs), std::istreambuf_iterator());`` – jpihl Jul 05 '16 at 11:37