【发布时间】:2012-10-10 16:32:00
【问题描述】:
我正在考虑编写不可复制的异常类。我觉得这很有趣,因为这样我就不必担心在复制构造函数中分配期间可能引发的异常。如果异常对象创建成功,则一切正常,std::terminate 应该没有问题。
struct exception
{
exception() = default;
exception(const exception&) = delete;
exception(exception&&) noexcept = default;
~exception() noexcept = default;
auto operator=(const exception&) -> exception& = delete;
auto operator=(exception&&) noexcept -> exception& = delete;
};
int main()
{
try {
try {
throw exception{};
} catch (...) {
std::rethrow_exception(
std::current_exception());
}
} catch (const exception& e) {
return 1;
}
}
GCC-4.7 和 Clang-3.2 接受上述代码。不过,我有点惊讶。据我所知,有几种情况可能会复制异常对象,例如std::current_exception() 和 std::rethrow_exception()。
问题:以上代码按照C++11是否正确,即所有符合C++11的编译器都能接受吗?
已编辑: 在示例中添加了 std::rethrow_exception 和 std::current_exception。两个编译器都接受这个版本。这应该清楚地表明,如果编译器在抛出异常时不需要复制构造函数,那么在使用这两个函数时编译器将不需要。
【问题讨论】:
-
您多久遇到一次异常对象抛出异常并导致终止的问题?
-
15.1/5 写道:“当抛出的对象是类对象时,复制/移动构造函数和析构函数应该是可访问的,即使复制/移动操作被省略。”
-
我只是想知道删除的函数是否被认为是可访问的(您的函数是公共的)。 8.4.3 没有提到任何关于此的内容。
-
@KerrekSB:我不知道异常类的抛出复制构造函数曾经终止我的一个程序。但是,我过去写过一些服务,它们必须在内存不足的情况下工作。有一些准则建议不要从异常的类复制构造函数中抛出异常,例如securecoding.cert.org/confluence/display/cplusplus/…