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

Dou*_*der 7 c++ exception auto-ptr

我在Exception类中遇到auto_ptr问题,我最终简化为:

#include <memory>

class MyException
{
    std::auto_ptr<int> m_foo2;
};

int main()
{
    try
    {
        throw MyException();
    }
    catch (const MyException&)
    {

    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这无法编译:

/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:note:候选者是:MyException :: MyException()/ perforce/unstable/test/Common/Exceptions/TestException4.cpp :4:注意:MyException :: MyException(MyException&)/ perforce/unstable/test/Common/Exceptions/TestException4.cpp:12:error:in thrown expression

如果我删除auto_ptr,错误就会消失.

这是因为正在复制或分配例外吗?有没有auto_ptr在异常中使用s 的方法?

Mik*_*our 9

这是因为正在复制或分配例外吗?

的确是.该标准指定了如何在C++ 11 15.1/3中抛出异常:

throw-expression初始化一个临时对象,[...].临时值是一个左值,用于初始化匹配处理程序中指定的变量.

使用隐式复制构造函数完成初始化.这被声明为MyException(MyException&),因为有一个成员需要一个非const引用参数(在C++ 11 12.8/9中指定).临时对象不能绑定到非const引用,因此构造失败.

有没有在异常中使用auto_ptrs的方法?

如果你能够使用C++ 11,那么你可以使用C++ 11 unique_ptr来代替auto_ptr历史.你的类将有一个隐式移动构造函数,声明为MyException(MyException&&),可用于从临时初始化它.

否则,您可以抛出一个非临时值:

MyException ex;
throw ex;
Run Code Online (Sandbox Code Playgroud)

或者你可以const通过添加一个显式的复制构造函数并使用const_castmutable允许复制auto_ptr- 来修改你的类以允许从引用初始化- 但这有潜在危险,我不建议它.