41

I am learning C++ from a book, and am on a exercise question below:

Write a function that takes and returns an istream&. The function should read the stream until it hits end-of-file. The function should print what it reads to the standard output. Reset the stream so that it is valid before returning the stream.

The below is my attempt:

#include "stdafx.h" #include <iostream> #include <istream> #include <string> #include <string.h> #include <list> #include <vector> #include <fstream> std::istream ReadFile(std::istream &iStream) { std::string word; while (iStream >> word) {} std::cout << "I read value " << word << std::endl; iStream.setstate(std::ios::goodbit); return iStream; } int _tmain(int argc, _TCHAR* argv[]) { ReadFile(std::cin); system("pause"); return 0; } 

However, I am getting errors at the return iStream line:

Error1 error C2280: 'std::basic_istream<char,std::char_traits<char>>::basic_istream(const std::basic_istream<char,std::char_traits<char>> &)' : attempting to reference a deleted function 2 IntelliSense: function "std::basic_istream<_Elem, _Traits>::basic_istream(const std::basic_istream<_Elem, _Traits>::_Myt &) [with _Elem=char, _Traits=std::char_traits<char>]" (declared at line 77 of "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\istream") cannot be referenced -- it is a deleted function 

I don't really know what these errors are. I am aware you can delete stuff, but I am not onto that topic in the book yet. As far as I know, I have not at all touched the istream file.

Can someone help me, please?

2
  • 1
    ReadFile should return std::istream & - and iStream.clear() rather than iStream.setstate(std::ios::goodbit) Commented Sep 13, 2014 at 21:37
  • 1
    I had this error when porting a project to a Visual Studio 2015 UWP app. I added a copy constructor to the class it was complaining about, and problem solved. Commented Dec 28, 2015 at 16:56

2 Answers 2

71

You can’t return an istream by value because it’s not copyable.

Since it’s not copyable the copy constructor has been deleted (to enforce the non-copyability), and that’s the direct technical cause of the diagnostic.

So, instead of

std::istream ReadFile(std::istream &iStream) 

… do

std::istream& ReadFile(std::istream& iStream) 

In other news, …


Instead of

#include "stdafx.h" 

just turn off precompiled headers in the Visual Studio project settings.

This also gives you more standard-conforming behavior for header inclusions.

If you don’t do that, then configure the project so that any warning about skipping an include, yields a hard compilation error.


Instead of

iStream.setstate(std::ios::goodbit); 

… do

istream.clear(); 

Instead of the non-portable Microsoft monstrosity

int _tmain(int argc, _TCHAR* argv[]) 

just use standard

int main() 

or in C++11 trailing return type syntax,

auto main() -> int 

Instead of

system("pause"); 

simply run your program via Ctrl+F5 in Visual Studio. Or, place a breakpoint on the last right brace of main and run in the debugger. Or, run the program from the command line.


The exercise formulation

should read the stream until it hits end-of-file

is ambiguous, but anyway reading words, as you’re doing, does not faithfully reproduce whitespace in the stream. For a more accurate reproduction of the stream contents you can either read character by character, or (via getline) line by line. Or, you can use a special mechanism for this task, namely outputting the read buffer, which does everything in one little statement.


Finally, you don’t need all those headers. You only need <iostream>, and if you choose to read lines, also <string>. Also, you don’t need the return 0; at the end of main, because that’s the default.

Sign up to request clarification or add additional context in comments.

3 Comments

Don't you normally declare references by "&d", how come you have put the reference infront of the return type or why does it not work as &std::istream? I am using the headers just so I can practice/try different stuff while am learning. Like using vectors for certain problems or something. Also I don't understand why my way of reading words is bad, I mean I know it is bad but I don't understand why.
@user3216729: the syntax for a declaration of a named reference starts with Type & name. You can put that as Type& name or as Type &name. In C++, with its focus on strong typing, Type& is natural, while in variable-oriented C (if C had references, which it doesn't!) &name, as you had written, would be more natural. The latter way makes it more clear what a declaration with multiple names means, important in C. In C++ one should just avoid declarations with multiple names.
@user3216729: regarding reading words, if, as the exercise somewhat implies, the point is to reproduce the stream contents, then reading words can't tell you about how much whitespace there is between words, like spaces, tabs, newlines, so that can't be reproduced. Note however that in Windows only purely textual stream contents can be faithfully reproduced by a purely standard C++ program, even when reading byte by byte, because text mode wreaks havoc with line endings and ASCII 26 (Ctrl Z), which for Windows text is interpreted as end of file.
8

A deleted function is a special function (constructor, destructor, operator) that has been explicitly disabled. If you look carefully at the error you can see that the function is the basic_istream copy-constructor, which is disabled because istreams cannot be copied. You are attempting to copy the istream when you return istream, since your function is declared as returning an istream (rather than e.g. returning a reference to an istream).

1 Comment

Um I am looking at the errors and I don't really get the syntax. Such as "<_Elem,_Traits>" No clue what that is, but I will learn as I go on. However I understand what my overall problem was now and how to fix it, thanks for the help!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.