7

我在 Exception 类中遇到了 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:在函数'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在异常中使用 s?

4

1 回答 1

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_castmutable允许它复制来破解您的类以允许从引用初始化auto_ptr- 但这是潜在的危险,我不推荐它。

于 2012-04-05T10:52:45.433 回答