Namespaces
Variants

std::move_if_noexcept

来自 zh.cppreference.net
 
 
 
定义于头文件 <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)
将实参转换为亡值
(函数模板)