std::move_if_noexcept
| 定义于头文件 <utility>
|
||
template< class T >
/* see below */ move_if_noexcept( T& x ) noexcept;
|
(C++11 起) (C++14 起 constexpr) |
|
std::move_if_noexcept若其参数的移动构造函数不抛出异常,或不存在复制构造函数(仅移动类型),则获得该参数的右值引用;否则获得该参数的左值引用。它通常用于将移动语义与强异常保证结合使用。
若 std::move_if_noexcept 的返回类型为:
T&&若std::is_nothrow_move_constructible<T>::value || !std::is_copy_constructible<T>::value为true。- 否则,
const T&。
参数
| x | - | 待移动或复制的对象 |
返回值
std :: move ( x ) 或 x ,具体取决于异常保证要求。
复杂度
常量。
注释
例如,
std::vector::resize
会使用此机制,该操作可能需要分配新存储空间,然后将元素从旧存储空间移动或复制到新存储空间。若在此操作期间发生异常,
std::vector::resize
会撤销已执行的所有操作——这仅当使用
std::move_if_noexcept
来决定采用移动构造还是复制构造时才可能实现(除非复制构造函数不可用,此时无论如何都会使用移动构造函数,并可能放弃强异常保证)。
示例
#include <iostream> #include <utility> struct Bad { Bad() {} Bad(Bad&&) // 可能抛出异常 { std::cout << "Throwing move constructor called\n"; } Bad(const Bad&) // 同样可能抛出异常 { std::cout << "Throwing copy constructor called\n"; } }; struct Good { Good() {} Good(Good&&) noexcept // 不会抛出异常 { std::cout << "Non-throwing move constructor called\n"; } Good(const Good&) noexcept // 不会抛出异常 { std::cout << "Non-throwing copy constructor called\n"; } }; int main() { Good g; Bad b; [[maybe_unused]] Good g2 = std::move_if_noexcept(g); [[maybe_unused]] Bad b2 = std::move_if_noexcept(b); }
输出:
Non-throwing move constructor called Throwing copy constructor called
参见
|
(C++11)
|
转发函数实参,并通过模板类型参数保持其值类别
(函数模板) |
|
(C++11)
|
将实参转换为亡值
(函数模板) |