Namespaces
Variants

std:: move_if_noexcept

From cppreference.net
Utilities library
定义于头文件 <utility>
template < class T >
/* 见下文 */ move_if_noexcept ( T & x ) noexcept ;
(C++11 起)
(C++14 起为 constexpr)

std::move_if_noexcept 在移动构造函数不抛出异常或不存在拷贝构造函数(仅移动类型)时获取其参数的右值引用,否则获取其参数的左值引用。它通常用于将移动语义与强异常保证相结合。

std::move_if_noexcept 的返回类型是:

目录

参数

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)
将实参转换为亡值
(函数模板)