Is this use of callbacks idiomatic? - c++

I noticed a common pattern in some of my code
std::string line;
if (!in || !std::getline(in, line)) {
throw line_read_error(in,line_counter);
}
++line_counter;
std::istringstream sin{line};
// ...read from sin...
if (!sin.eof()) {
sin.clear();
throw incomplete_read_error(in,line_counter,sin.tellg());j
}
What I read from the line was different in each location, but the setup and post-read check were identical.
I factored it out, creating an object to hold my in stream and line_counter, and passing a callback
for the body:
class LineReader {
std::istream& in;
size_t line_counter;
public:
template <typename Function>
void with_next_line(Function callback) {
std::string line;
if (!in || !std::getline(in, line)) {
throw line_read_error(in,line_counter);
}
++line_counter;
std::istringstream sin{line};
callback(sin);
if (!sin.eof()) {
sin.clear();
throw incomplete_read_error(in,line_counter,sin.tellg());j
}
}
// ...
}
Changing my uses to
line_reader.with_next_line([/*...*/](auto& sin){
// ...read from sin...
});
This is certainly less repetition, but it's still a bit awkward.
What I'm really concerned with, however, is whether it'll be easy for other
people to follow, as I'm really trying to make my code as legible as possible.
Would I be better off with something like
auto sin = line_reader.get_next_line();
// ...read from sin...
line_reader.check_done(std::move(sin));

The normal way to do setup + cleanup is to have an object whose constructor does the setup and destructor does the cleanup (RAII).
However, the cleanup you want to do, is to throw if you haven't read to the end - and throwing from a destructor is evil, bad, and wrong. That means you can't use RAII in this particular case.
If it is really important to do the check, then the code you have will enforce it. If it is just "a good idea", then I think the two calls (before and after) is probably slightly cleaner than the lambda. (I wouldn't bother with the std::move(sin) - using a move doesn't really add anything here.)

Related

Stop process if there is an error in the constructor

In a utility class file, I want to open a file to read or write it.
If I can't open it, I don't want to continue the process.
FileUtility::FileUtility(const char *fileName) {
ifstream in_stream;
in_stream.open(filename);
}
FileUtility fu = FileUtility("bob.txt");
fu.read();
fu.write();
File bob.txt doesn't exist, so I don't want method to read and write.
Is there a clean way to do it?
When construction of an object fails in C++, you should throw an exception, or propagate the exception from the failed construction of the subobject.
FileUtility(const char* filename) {
std::ifstream in_stream;
in_stream.exceptions(std::ios_base::failbit);
in_stream.open(filename); // will throw if file can't be opened
}
In the calling code you can choose to handle the exception:
try {
FileUtility fu = FileUtility("bob.txt");
} catch (std::ios_base::failure) {
printf("Failed to open bob.txt\n");
exit(EXIT_FAILURE);
}
// do other stuff
Or, if you don't catch the exception, the runtime will just call std::terminate(), which will print out its own error message, which may or may not be helpful:
terminate called after throwing an instance of 'std::ios_base::failure'
what(): basic_ios::clear
Aborted
There are generally four ways error state can be communicated from a callee to a caller:
1. Direct return value (return code or OUT parameter).
A return code is not possible for a constructor call, although an OUT parameter is. However, it's somewhat invasive to require every function to provide its return code or an OUT parameter for this purpose, so I don't like this solution in general, although it is certainly heavily used in various libraries and APIs. You could use this approach by adding a pointer or reference parameter to your constructor, to which the caller could provide the address of some local error variable, into which the constructor could store a possible return value. I don't recommend this.
2. Exceptions.
There is a somewhat polarized debate on the pros and cons of exceptions, in both C++ code and in other languages. I may take some downvotes for saying this, but my personal opinion is that exceptions should be avoided like the plague. See http://www.joelonsoftware.com/items/2003/10/13.html for someone who shares my view. But this is a workable solution if you're so inclined. See #Brian's answer for a good demonstration of this solution.
3. Object attribute.
The std::ifstream object actually does this, so you can leverage that. (Actually, from your example code, you define your std::ifstream as a local variable in the constructor, which implies it won't persist after the call, but since you call some kind of read() and write() methods on the constructed object, that implies that you do persist it after the call, so I'm going to assume the latter is the correct inference.) You can leverage that, by calling std::ifstream::is_open(). If you want to maintain encapsulation of the std::ifstream, you can define your own is_open() equivalent on FileUtility that will simply return in_stream.is_open();, again, assuming it is retained as an attribute on your FileUtility class.
struct FileUtility {
ifstream ifs;
FileUtility(const char* fileName);
bool is_open(void) const;
};
FileUtility::FileUtility(const char* fileName) { ifs.open(fileName); }
bool FileUtility::is_open(void) const { return ifs.is_open(); }
FileUtility fu = FileUtility("bob.txt");
if (!fu.is_open()) return 1;
Alternatively, you could create a whole new error state layer just for the FileUtility class, and propagate the std::ifstream error through that. For example:
struct FileUtility {
static const int ERROR_NONE = 0;
static const int ERROR_BADFILE = 1;
ifstream ifs;
int error;
FileUtility(const char* fileName);
};
FileUtility::FileUtility(const char* fileName) : error(ERROR_NONE) {
ifs.open(fileName);
if (!ifs.is_open()) { error = ERROR_BADFILE; return; }
}
FileUtility fu = FileUtility("bob.txt");
if (fu.error != FileUtility::ERROR_NONE) return 1;
These are reasonable solutions.
4. Global error state.
I wouldn't be surprised if some programmers were to respond with a "that sounds like a bad idea" reaction to this possible solution, but the truth is that many extremely successful and prominent code bases use this solution for communicating error state. Perhaps the best examples are the errno variable used by the C Standard Library (although it should be mentioned that errno sort of works in conjunction with direct return codes), and the GetLastError() system used by the Windows C API. I suppose some might argue that that's really the "C approach", and exceptions are the "C++ approach", but again, I avoid exceptions like the plague.
As an aside, multithreadedness is not a problem for this solution, because errno and GetLastError() both use thread-local error state, rather than true global error state.
I like this solution best, because it's simple, extremely uninvasive, and can easily be reused by different code bases, provided of course that you define the error framework (basically the thread-local variable and possibly the ERROR_NONE macro/global; see below) in its own library, in which case your code gains a consistency when it comes to error handling.
Example:
#define ERROR_NONE 0
thread_local int error = ERROR_NONE;
struct FileUtility {
static const int ERROR_BADFILE = 1;
ifstream ifs;
FileUtility(const char* fileName);
};
FileUtility::FileUtility(const char* fileName) {
ifs.open(fileName);
if (!ifs.is_open()) { error = ERROR_BADFILE; return; }
}
FileUtility fu = FileUtility("bob.txt");
if (error != ERROR_NONE) return 1;
This is the solution I'd recommend; otherwise I'd go with an object attribute solution.

C++ How to differentiate std::cin to std::ifstream?

I am trying to make a simple comparison to find if istream is a std::cin or std::ifstream.
My pseudocode is something like that:
class myclass
{
public:
void write(istream& is)
{
if(is == cin) // this does not work
{
//do something
}
else
{
//do something else
}
}
};
How can I proceed?
Thank you!
Since std::cin is an instance of std::istream, you could compare the addresses of the two objects to see if they are equal:
if (&is == &std::cin)
(Demo)
However I would consider investigating if you can achieve your goal without doing this; switching logic based on the identity of the stream argument is not very clean and may inhibit future development or maintenance of this project.
I'm not sure why you need to check if you have cin or not, but I had the same problem and my reason was: if I have cin, it means I'm in interactive mode, so I should give some useful information to cout. While checking the address of cin with is will probably hopefully always work, I wouldn't really trust it...
Anyways, my solution was to slightly generalize and add an extra parameter with a reasonable default
void f(istream &i, ostream *o = nullptr) {
if (o) {
*o << "useful info...";
}
i >> important_variable;
}
This gives a slightly more general function, using the "pointer to parameter means optional parameter" idiom. If you need cin for some other reason, then you may also look into specifically which properties of cin you need, and how to determine if your input stream possesses them.

check if something was serialized in std::ostream

Is there an easy way to check if something was serialized in stl::ostream. I am looking for something like:
some preparation
// ... a very complex code that may result in adding or not to the stream,
// that I will prefer not to change
check if the stream has something added
Note that this will need to works recursively. Is using register_callback is a good idea or there is easier way?
First the immediate question: register_callback() is intended to deal with appropriate copying and releasing of resources stored in pword() and will have operations only related to that (i.e., copying, assigning, and releasing plus observing std::locale changes). So, no, that won't help you at all.
What you can do, however, is to create a filtering stream buffer which observes if there was a write to the stream, e.g., something like this:
class changedbuf: std::streambuf {
std::streambuf* d_sbuf;
bool d_changed;
int_type overflow(int_type c) {
if (!traits_type::eq_int_type(c, traits_type::eof())) {
this->d_changed = true;
}
return this->d_sbuf->sputc(c);
}
public:
changedbuf(std::streambuf* sbuf): d_sbuf(d_sbuf), d_changed() {}
bool changed() const { return this->d_changed; }
}
You can use this in place of the std::ostream you already have, e.g.:
void f(std::ostream& out) {
changedbuf changedbuf(out.rdbuf());
std::ostream changedout(&changedbuf);
// use changedout instead of out; if you need to use a global objects, you'd
// replace/restore the used stream buffer using the version of rdbuf() taking
// an argument
if (changedbuf.change()) {
std::cout << "there was a change\n";
}
}
A real implementation would actually provide a buffer and deal with proper flushing (i.e., override sync()) and sequence output (i.e., override xsputn()). However, the above version is sufficient as a proof-of-concept.
Others are likely to suggest the use of std::ostringstream. Depending on the amount of data written, this can easily become a performance hog, especially compared to an advanced version of changedbuf which appropriately deals with buffering.
Are you passing the stream into the complex code, or is it globally visible? Can it be any kind of ostream or can you constrain the type to ofstream or ostringstream?
You may be able to use tellp to determine whether the file position has changed since your preparation code, if your ostream type supports it (such as with most fstreams). Or, if you're passing the stream in, you could pass an empty ostringstream in and check that it's not empty when the string is extracted to be printed out.
It's not entirely obvious which solution, if any, would be appropriate for you without knowing more about the context of your code and the specifics of your problem. The best answer may be to return (or set as a by-reference out-parameter) a flag indicating whether the stream was inserted into.

Is throwing an exception a healthy way to exit?

I have a setup that looks like this.
class Checker
{ // member data
Results m_results; // see below
public:
bool Check();
private:
bool Check1();
bool Check2();
// .. so on
};
Checker is a class that performs lengthy check computations for engineering analysis. Each type of check has a resultant double that the checker stores. (see below)
bool Checker::Check()
{ // initilisations etc.
Check1();
Check2();
// ... so on
}
A typical Check function would look like this:
bool Checker::Check1()
{ double result;
// lots of code
m_results.SetCheck1Result(result);
}
And the results class looks something like this:
class Results
{ double m_check1Result;
double m_check2Result;
// ...
public:
void SetCheck1Result(double d);
double GetOverallResult()
{ return max(m_check1Result, m_check2Result, ...); }
};
Note: all code is oversimplified.
The Checker and Result classes were initially written to perform all checks and return an overall double result. There is now a new requirement where I only need to know if any of the results exceeds 1. If it does, subsequent checks need not be carried out(it's an optimisation). To achieve this, I could either:
Modify every CheckN function to keep check for result and return. The parent Check function would keep checking m_results. OR
In the Results::SetCheckNResults(), throw an exception if the value exceeds 1 and catch it at the end of Checker::Check().
The first is tedious, error prone and sub-optimal because every CheckN function further branches out into sub-checks etc.
The second is non-intrusive and quick. One disadvantage is I can think of is that the Checker code may not necessarily be exception-safe(although there is no other exception being thrown anywhere else). Is there anything else that's obvious that I'm overlooking? What about the cost of throwing exceptions and stack unwinding?
Is there a better 3rd option?
I don't think this is a good idea. Exceptions should be limited to, well, exceptional situations. Yours is a question of normal control flow.
It seems you could very well move all the redundant code dealing with the result out of the checks and into the calling function. The resulting code would be cleaner and probably much easier to understand than non-exceptional exceptions.
Change your CheckX() functions to return the double they produce and leave dealing with the result to the caller. The caller can more easily do this in a way that doesn't involve redundancy.
If you want to be really fancy, put those functions into an array of function pointers and iterate over that. Then the code for dealing with the results would all be in a loop. Something like:
bool Checker::Check()
{
for( std::size_t id=0; idx<sizeof(check_tbl)/sizeof(check_tbl[0]); ++idx ) {
double result = check_tbl[idx]();
if( result > 1 )
return false; // or whichever way your logic is (an enum might be better)
}
return true;
}
Edit: I had overlooked that you need to call any of N SetCheckResultX() functions, too, which would be impossible to incorporate into my sample code. So either you can shoehorn this into an array, too, (change them to SetCheckResult(std::size_t idx, double result)) or you would have to have two function pointers in each table entry:
struct check_tbl_entry {
check_fnc_t checker;
set_result_fnc_t setter;
};
check_tbl_entry check_tbl[] = { { &Checker::Check1, &Checker::SetCheck1Result }
, { &Checker::Check2, &Checker::SetCheck2Result }
// ...
};
bool Checker::Check()
{
for( std::size_t id=0; idx<sizeof(check_tbl)/sizeof(check_tbl[0]); ++idx ) {
double result = check_tbl[idx].checker();
check_tbl[idx].setter(result);
if( result > 1 )
return false; // or whichever way your logic is (an enum might be better)
}
return true;
}
(And, no, I'm not going to attempt to write down the correct syntax for a member function pointer's type. I've always had to look this up and still never ot this right the first time... But I know it's doable.)
Exceptions are meant for cases that shouldn't happen during normal operation. They're hardly non-intrusive; their very nature involves unwinding the call stack, calling destructors all over the place, yanking the control to a whole other section of code, etc. That stuff can be expensive, depending on how much of it you end up doing.
Even if it were free, though, using exceptions as a normal flow control mechanism is a bad idea for one other, very big reason: exceptions aren't meant to be used that way, so people don't use them that way, so they'll be looking at your code and scratching their heads trying to figure out why you're throwing what looks to them like an error. Head-scratching usually means you're doing something more "clever" than you should be.

C++ - Where to throw exception?

I have some kind of an ideological question, so:
Suppose I have some templated function
template <typename Stream>
void Foo(Stream& stream, Object& object) { ... }
which does something with this object and the stream (for example, serializes that object to the stream or something like that).
Let's say I also add some plain wrappers like (and let's say the number of these wrappers equals 2 or 3):
void FooToFile(const std::string& filename, Object& object)
{
std::ifstream stream(filename.c_str());
Foo(stream, object);
}
So, my question is:
Where in this case (ideologically) should I throw the exception if my stream is bad? Should I do this in each wrapper or just move that check to my Foo, so that it's body would look like
if (!foo.good()) throw (something);
// Perform ordinary actions
I understand that this may be not the most important part of coding and these solutions are actually equal, but I just wan't to know "the proper" way to implement this.
Thank you.
In this case it's better to throw it in the lower-level Foo function so that you don't have to copy the validation and exception throwing code in all of your wrappers. In general using exceptions correctly can make your code a lot cleaner by removing a lot of data validation checking that you might otherwise do redundantly at multiple levels in the call stack.
I would prefer not to delay notifying an error. If you know after you have created the stream, that it is no good, why call a method that works on it? I know that to reduce code-redundancy you plan to move it further down. But the downside of that approach is a less-specific error message. So this depends to some extent on the source-code context. If you could get away with a generic error message at the lower-function level you can add the code there, this will surely ease maintanence of the code especially when there are new developers on the team. If you need a specific error message better handle it at the point of failure itself.
To avoid code redundancy call a common function that makes this exception/error for you. Do not copy/paste the code in every wrapper.
The sooner you catch the exceptiont the better. The more specific the exception is - the better. Don't be scared of including most of your code into a try catch blocks, apart fromt he declaration.
For example:
int count = 0;
bool isTrue = false;
MyCustomerObject someObject = null;
try
{
// Initialise count, isTrue, someObject. Process.
}
catch(SpecificException e)
{
// Handle and throw up the stack. You don't want to lose the exception.
}
I like to use helper functions for this:
struct StreamException : std::runtime_error
{
StreamException(const std::string& s) : std::runtime_error(s) { }
virtual ~StreamException() throw() { }
};
void EnsureStreamIsGood(const std::ios& s)
{
if (!s.good()) { throw StreamException(); }
}
void EnsureStreamNotFail(const std::ios& s)
{
if (s.fail()) { throw StreamException(); }
}
I test them immediately before and after performing stream operations if I don't expect a failure.
Traditionally in C++, stream operations don't throw exceptions. This is partly for historic reasons, and partly because streaming failures are expected errors. The way C++ standard stream classes deal with this is to set a flag on a stream to indicate an error has occurred, which user code can check. Not using exceptions makes resumption (which is often required for streaming ops) easier than if exceptions were thrown.