When I catch an exception, I want to emit a signal and pass that exception to a slot so it can be handled in a different thread. The signal and slot are connected using a Qt:QueuedConnection type.
I first tried this:
/*in .h*/
signals:
void exceptionOccured(const std::exception &e);
public slots:
void exceptionReceive(const std::exception &e);
/*in .cpp*/
connect(this,SIGNAL(exceptionOccured(const std::exception&)),this,SLOT(exceptionReceive(const std::exception&)),Qt::QueuedConnection);
try {
throw std::runtime_error("test");
} catch (std::exception &e) {
emit exceptionOccured(e);
}
This somewhat works, but as QT makes a copy of the referenced object to be placed on the queue, the exceptionReceived slot receives a std::exception type object and all additional information is lost.
I then tried to pass a pointer to the original exception object, but that gives me the problem that by the time the slot is called the actual object has disappeared.
How can I either tell QT to make a correct copy of the exception (the actually application has multiple levels of inheritance from std::exception) or turn the catch'ed exception into some safe pointer type (i.e. copy it from the stack to the heap or so).
P.S.
The object sends the message to itself because the try/catch statement is run from a lambda function using QtConcurrent::run();
std::exception_ptrwas added to the standard one C++11 in order to solve exactly this problem. std::current_exception() lets you get a handle to the current exception, and you can then pass it around and re-throw it in any thread you want.
Details at http://en.cppreference.com/w/cpp/error/exception_ptr.
If you insist on using the base exception type, then this is a C++ problem, not a Qt problem. You'd need to implement some type of a virtual copy constructor pattern. Once you do, Qt will do the right thing automagically.
One such pattern:
class clonable_exception : public std::exception {
protected:
virtual void clone_to(clonable_exception& dst) const = 0;
public:
clonable_exception() = default;
clonable_exception(const clonable_exception& src) {
src.clone_to(*this);
}
clonable_exception & operator=(const clonable_exception& src) {
src.clone_to(*this);
}
};
All signals and slots should use the clonable_exception type instead of std::exception.
Related
In a code review recently, I had some less than kind words for something I thought awful. It turns out that it was obviously inspired by the QuantLib::Error class, which looks like this:
//! Base error class
class Error : public std::exception {
public:
/*! The explicit use of this constructor is not advised.
Use the QL_FAIL macro instead.
*/
Error(const std::string& file,
long line,
const std::string& functionName,
const std::string& message = "");
#ifdef QL_PATCH_MSVC_2013
/*! the automatically generated destructor would
not have the throw specifier.
*/
~Error() throw() override {}
#endif
//! returns the error message.
const char* what() const QL_NOEXCEPT override;
private:
ext::shared_ptr<std::string> message_;
};
Why is the member variable ext::shared_ptr<std::string> and not just plain std::string? What reason could there be to heap-allocate the string object itself? (The QuantLib code base seems to heap-allocate just about everything just about always just about everywhere, and pulls in shared_ptr's to cope with that - a classic anti-pattern - but doing it here as well "just for consistency" strikes me as a bit much. Am I missing something?)
This is following the behavior of standard library exception types.
They are supposed to be copyable without throwing exceptions, since throwing an exception during construction of an exception handler parameter would cause a call to std::terminate (and possibly in some other situations requiring a copy of the exception as well).
If std::string was used directly, copying the exception could cause for example a std::bad_alloc to be thrown. Using a reference-counted pointer instead avoids that.
Given a class and one of its member functions like this:
// constructor
class Stitcher::Stitcher(const std::vector<cv::Mat> imgs)
{
calibrate(imgs);
}
// one of its member functions that gets called upon construction
void Stitcher::calibrate(const std::vector<cv::Mat> imgs)
{
// Do some stuff here
}
When constructing this Stitcher object, it runs the calibrate function upon construction. However calibrate will sometimes fail and I need a way to handle such failures. I was thinking of returning a boolean but wasn't sure how to do that because I still need access to the Stitcher object for other member functions. Basically I am instantiating it like this currently: Stitcher stitcher(images); which works fine as long as it doesn't fail. Then I can use stitcher.stitch(), stitcher.otherFunction(), etc. Any suggestions for this C++ newbie on how to handle errors inside a class member function?
There is a RAII (Resource Acquisition Is Initialization) idiom which is highly recommended in C++. One of the aspects of the RAII is the idea that there should not exist badly constructed or uninitialized objects. From your question I conclude that you are trying to initialize the object, but sometimes that is impossible. That is the application of RAII.
In C++ constructor functions don't return error codes, so there is another technique to handle errors: exceptions. In brief exception thrown from the constructor don't allow you to leave the not-constructed-yet object in a partially constructed state.
class Stitcher {
public:
Stitcher(const std::vector<cv::Mat> &imgs) {
calibrate(imgs);
// If the calibrate method fails, the object is not being constructed.
// The next line will not be executed on a non-calibrated object:
doSmthWithCalibratedImgs(imgs);
}
private:
void calibrate(const std::vector<cv::Mat> &imgs) {
// Do some stuff here
// if cannot calibrate:
throw exception("Cannot calibrate");
}
};
So the next task would be to handle possible exceptions from the code that constructs Stitcher objects.
Note that I've changed the signature of the methods to pass the vector by const reference: I guess that is what you need. Another thing that you might need is to store the imgs vector inside of the object as a data member, but that depends on the task and is up to you.
What you could do is throw an exception to indicate a problem that occurs during the execution of your program. The standard library has a number of exception classes that you could use for throwing an exception, all of which derive from std:exception. For example, std::out_of_range.
To throw a standard exception you create a string that describes the exception and use it to initialise the exception object:
std::string s("my exception")
...
throw std::out_of_range(s);
You can also write:
throw std::out_of_range("out of from somewhere");
using implicit conversion from char* to std::string.
Another possibility is to define your own special exception class, derived directly or indirectly from std::exception. However, you have to provide the overridden virtual function what() in your class:
class MyException: public std::exception
{
public:
MyException(...){
}
virtual const char* what() const throw() {
return "C++ Exception";
}
};
Another way to provide the what() function is to derive your exception class from one of the classes that have a string constructor for the what() argument:
class MyException: public std::out_of_range
{
public:
MyException(const std::string &what): std::out_of_range(what) {}
};
Like this you can different classes for different types of exceptions.
Now can you throw an exception in Stitcher::calibrate() but you have to have try...catch block to catch it. Something like this:
try
{
Stitcher stitcher;
// this will be executed if no exception is thrown
}
catch (const std::exception &e)
{
std::cout << e.what();
}
The first question you have to answer is (regarding your business logic): should failure of calibrate(imgs) also imply failure of constructing object of type Stitcher.
1. Possibility:
calibrate(imgs) fails, but the object is constructed. You would need some member methods (something like isCalibrated(..), recalibrate()... etc.), to be able to query object if the calibration was succesful, and maybe try to recalibrate if the predonditions are met at some other time, etc.
2. Possibility:
Stitcher constructor postcondition is, that calibration was successful. In this case, you can't tolerate the failure, so you have to throw exception within constructor.
Regarding this, you will maybe have to decide, what kind of exception safty guarantee you would aim to offer.
You have 3 choices here:
i) strong exception safety guarantee (best choice, if possible)
ii) basic exception safety gurantee (second best choice)
iii) no exception safety guarantee (worst choice)
Basically, doing work in the constructor is not a good practice. You could consider constructig Stitcher by setting up the required data members in the contructor and meet all necessary preconditions, and then provide some member methods like for ex. Calibrate()-with return false by failure, TryCalibrate()-which throws exception, etc., so the clients of Stitcher have better control about failure handling.
This question has been asked before but not answered satisfactorily.
I have a class which is acting as an event handler and I would like to have a nice syntax for calling the event handler outside of an event. What this boils down to is overriding the () operator. I currently have
class EventHandler
{
public:
void Call(void* sender, EventArgs e);
void operator() (void* sender, EventArg e){ Call(sender, e); }
};
which works fine. I can call the event handler via
EventHandler EH;
EH(nullptr, EventArgs::Empty());
My problem lies in that I usually store the event handler on the heap so I need
EventHandler* EH;
EH(nullptr, EventArgs::Empty()); // error but this is the syntax I'm hoping for
but this can only be done with
EventHandler* EH;
(*EH)(nullptr, EventArgs::Empty()); // no error
How can I override the () operator to have it work with the pointer to the EventHandler object? I have seen some things that look like overloading the ->() operator instead of just the () operator but I haven't been able to make sense of it.
The operator ->() doesn't exists.
There are two ways to call the operator.
EventHandler* EH;
(*EH)(nullptr, EventArgs::Empty());
or
EventHandler* EH;
EH->operator()(nullptr, EventArgs::Empty());
This works in the same way as the operator= or any other operator
"My problem lies in that I usually store the event handler on the heap so I need"
Is there a reason for this? If the EH involves a large amount of state, then perhaps you could build a wrapper class that put the state on the heap but that itself was allocated as an object. This would allow overloading operator()() and getting the desired syntax, while forwarding to the underlying implementation. Basically refactor to a Pimpl in order to get the syntax you want in the objects that you use in your interface.
It is often a good idea to wrap your heap allocation details in a regular type, and use the regular type rather than a pointer.
class EventHandler_Impl {
public:
void Call(void* sender, EventArgs e);
void operator() (void* sender, EventArg e){ Call(sender, e); }
};
then we write:
struct EventHandler {
void operator()(void* sender, EventArg e){ (*pImpl)(sender, e); }
private:
std::unique_ptr<EventHandler_Impl> pImpl;
};
we have a "regular" type EventHandler that stores a pointer to the "actual" class. It has methods that forward to the pImpl.
The state of this class is just one pointer. It automatically deletes the pImpl when it goes out of scope. The std::unique_ptr has the overhead of a pointer (which you'd store instead), except it destroys the pImpl object when it goes out of scope.
You can make it move-only, or manually implement a copy constructor (adding to the _Impl interface the ability to clone itself).
It is a bit of boilerplate.
You can do away with writing methods in the _Impl by simply writing them in the regular type, and having them access only state through the pImpl pointer if you choose.
You can't. EventHandler* is a pointer to a type, which is simply not callable.
You could use another functor as a wrapper, you'd only need to call it in a slightly different way.
struct EventHandlerCaller
{
void operator() (EventHandler* eh, void* sender, EventArg& e)
{
eh->operator()(nullptr, sender, e);
}
}
static EventHandlerCaller caller;
EventHandler* EH;
caller(eh, nullptr, EventArgs::Empty());
I'm writing a function, wd_sprintf, to provide a sprintf-like API. Under the covers, it uses the boost library.
If the user of wd_sprintf codes the format string improperly, boost::format will throw an exception. I'd like for my function to intercept the exception, repackage it in a message that identifies wd_sprintf as the locus of the error, and rethrows the exception.
What I can't figure out is what to catch, and how to extract the message.
// wd_sprintf(pattern [,args...]):
//
// This creates a temporary boost::format from pattern, and calls
// wd_sprintf_r() to recursively extract and apply arguments.
#include <boost/exception/all.hpp>
class wd_sprintf_exception : std::runtime_error {
public:
wd_sprintf_exception(string const& msg : std::runtime_error(msg) {}
};
template <typename... Params>
string
wd_sprintf (const string &pat, const Params&... parameters) {
try {
boost::format boost_format(pat);
return wd_sprintf_r(boost_format, parameters...);
}
catch (boost::exception e) {
const string what = string("wd_sprintf: ") + string(e.what());
throw wd_sprintf_exception(what);
}
}
Of course, this gets a compilation error because boost::exception is abstract.
(I've been to a number of sites and pages, including this one whose title was similar but which was full of '<<' operators inserting into a function call, template constructs like boost::get_error_info<my_tag_error_info>(e), and generally much more complexity than I suspect is really needed. I just need the above to work.)
You can't have an an automatic variable of an abstract type. You can, however, have a reference or pointer to one. The reason for this is that the compiler has no way of knowing exactly which derived type the variable actually is, so it doesn't know how much space to allocate for it or which class's copy constructor to use.
When you catch a boost::exception by value, as you're doing, the compiler has to make a local copy of it in your catch block; which it doesn't have enough information to do!
In your specific case, the best solution is to catch a reference to the original exception.
In regards to catching exceptions from Boost.Format, it throws exceptions derived from boost::io::format_error, which is derived from std::exception, not boost::exception. You should be catching boost::io::format_error.
I have run into broken compiler, which does not allow exceptions to inherit from std::exception (nvcc 3.0).
so had to create workaround:
struct exception {
explicit exception(const char* message) {
what_ = message;
}
virtual const char *what() const throw() { return what_; }
operator std::exception() const {
return std::runtime_error(what_);
}
private:
const char* what_;
};
struct configuration_error : exception {
configuration_error(const char* message)
: exception(message) {}
};
is there something I am going to lose by not inheriting from exception, instead providing cast? is what necessary in the above case?
thank you
catch (std::exception) will not catch your exception, and you cannot dynamic_cast your exception to std::exception either. If your program never does either of those things, you're fine.
Personally I would not use a compiler this broken, though.
You should upgrade to CUDA 3.1.
If you're trying to create an instance of something derived from std::exception on the device, it won't work because the std::exception constructor would need to be called, and that is not a device function.
Throwing and catching your own type is probably the solution. Since it probably will never make it back to host code, though (C++ doesn't really handle throwing multiple exceptions in parallel), compatibility with std::exception shouldn't be too much of an issue.