我在异常类中遇到auto_ptr问题,我最终简化为:
#include <memory>
class MyException
{
std::auto_ptr<int> m_foo2;
};
int main()
{
try
{
throw MyException();
}
catch (const MyException&)
{
}
return 0;
}
无法编译:
/perforce/unstable/test/Common/Exceptions/TestException4.cpp:In function'int main()': /perforce/unstable/test/Common/Exceptions/TestException4.cpp:12: 错误:没有匹配的函数用于调用 'MyException :: MyException(MyException)' /perforce/unstable/test/Common/Exceptions/TestException4.cpp:4:注意: 候选人是:MyException :: MyException() /perforce/unstable/test/Common/Exceptions/TestException4.cpp:4:注意: MyException :: MyException(MyException&安培;) /perforce/unstable/test/Common/Exceptions/TestException4.cpp:12: 错误:抛出表达式
如果删除auto_ptr,错误就会消失。
这是因为正在复制或分配例外吗?有没有办法在异常中使用auto_ptr
?
答案 0 :(得分:9)
确实如此。该标准指定了如何在C ++ 11 15.1 / 3中抛出异常:这是因为正在复制或分配异常吗?
throw-expression初始化一个临时对象,[...] 临时值是一个左值,用于初始化匹配处理程序中指定的变量。
使用隐式复制构造函数完成初始化。这被声明为MyException(MyException&)
,因为有一个成员需要非const
引用参数(如C ++ 11 12.8 / 9中所指定)。临时对象不能绑定到非const
引用,因此构造失败。
有没有办法在异常中使用auto_ptrs?
如果您能够使用C ++ 11,那么您可以使用unique_ptr
代替,并将auto_ptr
托付给历史记录。你的类将有一个隐式移动构造函数,声明为MyException(MyException&&)
,可用于从临时初始化它。
否则,您可以抛出非临时值:
MyException ex;
throw ex;
或者您可以通过添加显式复制构造函数并使用const
或const_cast
来允许复制mutable
,从而允许您的类允许从auto_ptr
引用进行初始化 - 但这有潜在危险,我不推荐它。