0
votes

I'm using the following code (using namespace std) to convert contents of a file to string.

Code 1

string fileToString(const string& filename)
{
    ifstream file(filename, ios::binary);
    if (!file) return "";
    string str(istreambuf_iterator<char>(file),
               (istreambuf_iterator<char>()));
    return str;
}

I find it weird that the code above works (I matched string::size() with actual file size found in Windows Explorer), but the following code doesn't:

Code 2

string fileToString(const string& filename)
{
    ifstream file(filename, ios::binary);
    if (!file) return "";
    string str(istreambuf_iterator<char>(file),
               istreambuf_iterator<char>());
    return str;
}

Note the missing parentheses around second parameter. The second function gives the following compiler error:

1 error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const std::basic_string<_Elem,_Traits,Ax> &)' : cannot convert parameter 1 from 'std::string (_cdecl *)(std::istreambuf_iterator<_Elem,_Traits>,std::istreambuf_iterator<_Elem,Traits> (_cdecl *)(void))' to 'const std::basic_string<_Elem,_Traits,_Ax> &'

2 IntelliSense: no suitable constructor exists to convert from "std::string (std::istreambuf_iterator> file, std::istreambuf_iterator> (*)())" to "std::basic_string, std::allocator>"

I'm using Visual Studio 2010, Win32 Console Application on Windows XP SP3.

To my surprise, the following code compiles and works as expected:

Code 3

string fileToString(const string& filename)
{
    ifstream file(filename, ios::binary);
    if (!file) return "";
    return string(istreambuf_iterator<char>(file),
                  istreambuf_iterator<char>());
}

Why does Code 2 produce compiler error?

1
I asked a very similar question some time ago: stackoverflow.com/questions/8927939/…jrok

1 Answers

3
votes

Why does Code 2 produce compiler error?

Code 2 produces compilation-error because in Code 2, the following line declares a function:

string str(istreambuf_iterator<char>(file),
           istreambuf_iterator<char>());

It declares a function. The function name is str . The return type is string. The function takes two parameters:

  • first parameter is of type istreambuf_iterator<char>.
  • second parameter is of type istreambuf_iterator<char> (*)() which is function pointer type which returns istreambuf_iterator<char> and takes no argument.

So in Code 2, you return a function called str. Since it cannot be converted into string which is the return type of the function fileToString, hence it gives compilation error.

In Code1 and Code3, there is no such issue, hence they work as expected.