Reputation: 16331
So lets say I have:
struct test {
bool a;
int b;
};
int main()
{
std::unique_ptr<test> ptr;
// don't init the ptr
try
{
if (!ptr->a)
{
std::cout << "ok" << std::endl;
}
}
catch (const std::exception &ex)
{
std::cout << "ex: " << ex.what() << std::endl;
}
return 1;
}
So here I setup a unique pointer, but I don't init it (to simulate this in a larger code base) but I want to catch the exception.
The problem is that my exception is not called - I just get a crash (memory access fault)
I read a few similar questions (but not quite the same) that suggested that I pass the exception by reference - but this did not work.
So is it possible to catch a unique_ptr de-reference exception?
EDIT: I should add that this is on Windows 7 box running MSVS2012 executable - incase it is relevant!
Upvotes: 0
Views: 758
Reputation: 67723
So is it possible to catch a unique_ptr de-reference exception?
There is no unique_ptr
dereference exception to catch.
As the documentation says,
The behavior is undefined if
get() == nullptr
You can easily write your own smart pointer with this Java-like behaviour, but it does mean paying for a test-and-branch on every dereference, which in general seems silly.
For the slightly different problem described in comments:
I have a list of unique_ptr's - I was trying to avoid individually checking each one by putting a try block around it.
the sane solution is probably to check it once and not on every subsequent dereference:
if(any_of(begin(ptrs), end(ptrs), logical_not<unique_ptr<test>>{})
{
throw MyNullPointerException();
}
Per subsequent comments, you could just add a check-and-throw wrapper to your constructing function.
In C++17 you can almost get what you want by instead returning an optional<unique_ptr<test>>
(ie, it either contains a populated unique_ptr
, or nothing at all: in that case, calling value
to extract the unique_ptr
would throw std::bad_optional_access
if there isn't really one there).
If you can import ot (or don't have C++17), the GSL is probably even better with gsl::not_null<T>
. For example, you could instead store these things in your container
using unique_not_null = std::unique_ptr<gsl::not_null<test>>;
Upvotes: 4