I have a problem with auto_ptr in Exception classes, that I eventually reduced to:
#include <memory>
class MyException
{
std::auto_ptr<int> m_foo2;
};
int main()
{
try
{
throw MyException();
}
catch (const MyException&)
{
}
return 0;
}
This fails to compile with:
/perforce/unstable/test/Common/Exceptions/TestException4.cpp: In function 'int main()': /perforce/unstable/test/Common/Exceptions/TestException4.cpp:12: error: no matching function for call to 'MyException::MyException(MyException)' /perforce/unstable/test/Common/Exceptions/TestException4.cpp:4: note: candidates are: MyException::MyException() /perforce/unstable/test/Common/Exceptions/TestException4.cpp:4: note: MyException::MyException(MyException&) /perforce/unstable/test/Common/Exceptions/TestException4.cpp:12: error: in thrown expression
And the error goes away if I remove the auto_ptr.
Is this because the exception is being copied or assigned? Is there a way of using auto_ptr
s in an Exception?
Is this because the exception is being copied or assigned?
Indeed it is. The standard specifies how an exception is thrown in C++11 15.1/3:
A throw-expression initializes a temporary object, [...]. The temporary is an lvalue and is used to initialize the variable named in the matching handler.
The initialisation is done with the implicit copy constructor. This is declared as MyException(MyException&)
, since there is a member that requires a non-const
reference argument (as specified in C++11 12.8/9). The temporary object can't be bound to a non-const
reference, and so the construction fails.
Is there a way of using auto_ptrs in an Exception?
If you're able to use C++11, then you could use unique_ptr
instead, and consign auto_ptr
to the bowels of history. Your class would have an implicit move constructor, declared as MyException(MyException&&)
, which could be used to initialise it from a temporary.
Otherwise, you could throw a non-temporary value:
MyException ex;
throw ex;
or you could hack your class to allow initialisation from a const
reference by adding an explicit copy constructor and using const_cast
or mutable
to allow that to copy the auto_ptr
- but that is potentially dangerous, and I wouldn't recommend it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With