PDA

View Full Version : [Resolved] C++, ostream, and Clang: Call to implicitly-deleted copy constructor?




ArtOfWarfare
May 18, 2013, 06:05 PM
Here's everything that I can imagine is relevant from my code:
#include <fstream>
#include <iostream>

class knapsack
{
public:
// ... more functions above ...
ostream putSolutionIn(ostream &ostr) const;
// ... more functions below ...
};

// implementations that I don't think are relevant...

ostream knapsack::putSolutionIn(ostream &ostr) const
{
ostr << "Total value: " << getValue() << endl;
ostr << "Total cost: " << getCost() << endl << endl;

// Print out objects in the solution
for (int i = 0, n = getNumObjects(); i < n; i++)
{
if (isSelected(i))
{
ostr << i << " " << getValue(i) << " " << getCost(i) << endl;
}
}

return ostr; // Error: Call to implicitly-deleted copy constructor of 'ostream' (aka 'basic_ostream<char>')
}

Is there a header I'm missing? Any suggestions what I'm doing wrong? Is there a bug with Clang or the C++ STL?

(Am I the only one who feels like C and C++ both suck at handling text and files and that tasks that should be trivial pertaining to them just aren't?)



chown33
May 18, 2013, 06:38 PM
Wondering if this:
ostream knapsack::putSolutionIn(ostream &ostr) const

ought to be:
ostream & knapsack::putSolutionIn(ostream &ostr) const



(Am I the only one who feels like C and C++ both suck at handling text and files and that tasks that should be trivial pertaining to them just aren't?)

I don't think either language is notably "text and file" oriented. C++ streams are arguably more so than C's scanf() & printf() families of functions, but I see that more as damning with faint praise.

A lot depends on what the text is, what the files are, and what you need to do with them. I've generally had good luck with awk and shell scripts, but maybe that's just me. If you don't know awk, or a superset like perl, you're doing yourself a disservice if the first tool in your toolset for handling text is C or C++.

If I have a substantial task involving text, I always try to break it down into smaller parts. Sometimes that breakdown is enough to show what can be done with awk, bash, and occasionally others like tr or sort. If there are a few sub-functions that don't easily yield, only then do I think about writing in C (or Java, or whatever), and then only for the needed sub-functions.

There's a lot to be said for the modularity of using pipes and shell scripts to build up complex results from simpler elements. In fact, if it comes to writing in C (or whatever), I will usually try to design the program specifically for use in a pipeline.

gnasher729
May 18, 2013, 07:10 PM
As chown said, your function returns an ostream and not an ostream&. So why do you get an error message?

Your function has an ostream& parameter, so somewhere you have an original ostream object. When you return an ostream, a copy of that original ostream object has to be created. But you can't copy an ostream - you would then have two ostream objects that write to the same file; if you used both, that would be a sure recipe for disaster. To avoid this, ostream has no copy constructor. The copy constructor is explicitely deleted (otherwise some default constructor would be used), so that's why you get the error message.

ArtOfWarfare
May 18, 2013, 10:16 PM
As chown said, your function returns an ostream and not an ostream&. So why do you get an error message?

Your function has an ostream& parameter, so somewhere you have an original ostream object. When you return an ostream, a copy of that original ostream object has to be created. But you can't copy an ostream - you would then have two ostream objects that write to the same file; if you used both, that would be a sure recipe for disaster. To avoid this, ostream has no copy constructor. The copy constructor is explicitely deleted (otherwise some default constructor would be used), so that's why you get the error message.

Thank you for the answer and explanation :)

I feel silly now - I highlighted the & on my cheat sheet from one of my prior C++ classes.


I don't think either language is notably "text and file" oriented. C++ streams are arguably more so than C's scanf() & printf() families of functions, but I see that more as damning with faint praise.

A lot depends on what the text is, what the files are, and what you need to do with them. I've generally had good luck with awk and shell scripts, but maybe that's just me. If you don't know awk, or a superset like perl, you're doing yourself a disservice if the first tool in your toolset for handling text is C or C++.

If I have a substantial task involving text, I always try to break it down into smaller parts. Sometimes that breakdown is enough to show what can be done with awk, bash, and occasionally others like tr or sort. If there are a few sub-functions that don't easily yield, only then do I think about writing in C (or Java, or whatever), and then only for the needed sub-functions.

My current goto languages for handling lots of text and/or files is Objective C or Java. They may not be the best, but of the languages I know (C, C++, Obj-C, Java, and some JS/JQ) they seem best suited for it... plus I have libraries of functions for NSStrings I've built up over the years + a lot of great .jars I've found.

I'm thinking the next language I will learn will probably be Ruby... I've noticed a lot of job descriptions mention it and my understanding is it handles text and files really well (plus I'm interested in making more server side applications.)

chown33
May 19, 2013, 11:34 AM
Awk is a simple language, as languages go. It's also specialized for processing text, rather than being general purpose. Its power lies in regular expressions, weak typing, and its fundamental design. If it takes you more than a week to learn, it's because you'll have to learn reg-ex's.

It's designed as a pattern-matching and processing language. The input (filename args, or stdin) is automatically read into lines and split into words. Your program is a series of pattern/action tuples, where the patterns are tested in order, and the corresponding action is applied. In general-purpose languages, all those steps (open files, read lines, split, match a pattern, do an action) have to be written explicitly. In awk, all of that is implicit and automatic.