Mot*_*tti 5 c++ exception move-semantics
C++ 中关于异常的最佳实践似乎是按值抛出,按引用捕获。我看了看<exception>和cppreference,我看到它std::exception有一个复制构造函数但没有移动构造函数,这是为什么?难道没有移动构造函数可以廉价地按值捕获从而简化指导方针吗?
的后代std::exception拥有数据。例如std::runtime_error拥有它的what()消息。该消息是动态分配的,因为它可以是任意长的消息。
但是,复制构造函数被noexcept(隐式)标记,因为std::exception复制构造函数是noexcept.
#include <stdexcept>
#include <type_traits>
int
main()
{
static_assert(std::is_nothrow_copy_constructible<std::runtime_error>{});
}
Run Code Online (Sandbox Code Playgroud)
类拥有动态分配的消息并具有复制构造函数的唯一方法noexcept是共享该所有权(引用计数)。所以std::runtime_error本质上是一个常量、引用计数的字符串。
根本没有动机为这些类型提供移动构造函数,因为复制构造函数不仅已经非常快,而且程序的异常路径仅在特殊情况下执行。移动构造函数唯一std::runtime_error能做的就是消除原子增量/减量。没有人关心。
拥有移动构造函数难道不会允许以廉价的方式捕获值,从而简化指导方针吗?
您已经可以按价值便宜地捕获。但该准则的存在是因为异常通常是继承层次结构的一部分,并且按值捕获会分割异常:
#include <exception>
#include <iostream>
#include <stdexcept>
int
main()
{
try
{
throw std::runtime_error("my message");
}
catch (std::exception e)
{
std::cout << e.what() << '\n';
}
}
Run Code Online (Sandbox Code Playgroud)
输出(对我来说):
std::exception
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
123 次 |
| 最近记录: |