为什么我不能在Exception类中使用auto_ptr

时间:2012-04-05 10:32:11

标签: c++ exception auto-ptr

我在异常类中遇到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

1 个答案:

答案 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;

或者您可以通过添加显式复制构造函数并使用constconst_cast来允许复制mutable,从而允许您的类允许从auto_ptr引用进行初始化 - 但这有潜在危险,我不推荐它。