C++ 为什么可以';我在一个异常类中有一个auto_ptr

C++ 为什么可以';我在一个异常类中有一个auto_ptr,c++,exception,auto-ptr,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; } #包括 类M

我对异常类中的auto_ptr有一个问题,我最终将其归结为:

#include <memory>

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

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

    }
    return 0;
}
#包括
类MyException
{
std::auto_ptr m_foo2;
};
int main()
{
尝试
{
抛出MyException();
}
捕获(常量MyException&)
{
}
返回0;
}
无法通过以下方式编译:

/性能/不稳定/测试/常见/异常/测试异常4.cpp:In 函数“int main()”: /性能/不稳定/测试/常见/异常/测试异常4.cpp:12: 错误:没有用于调用的匹配函数 'MyException::MyException(MyException)' /性能/不稳定/测试/常见/异常/测试异常4.cpp:4:注: 候选对象是:MyException::MyException() /性能/不稳定/测试/常见/异常/测试异常4.cpp:4:注: MyException::MyException(MyException&) /性能/不稳定/测试/常见/异常/测试异常4.cpp:12: 错误:在抛出的表达式中

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

这是因为正在复制或分配异常吗?有没有办法在异常情况下使用
auto_ptr
s

这是因为正在复制或分配异常吗

的确如此。该标准规定了在C++11 15.1/3中如何引发异常:

抛出表达式初始化临时对象[…]。 临时变量是一个左值,用于初始化匹配处理程序中命名的变量

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

是否有一种在异常情况下使用auto_ptrs的方法

如果您能够使用C++11,那么您可以使用
unique\u ptr
,并将
auto\u ptr
交付给历史。您的类将有一个隐式move构造函数,声明为
MyException(MyException&&)
,可以使用它从临时类初始化它

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

MyException ex;
throw ex;

或者你可以通过添加一个显式的复制构造函数,并使用
const\u cast
mutable来允许类从
const
引用中进行初始化,从而允许类复制
auto\u ptr
——但这有潜在的危险,我不建议这样做。

Wow,这里有高质量的答案。一定是个好问题。:)