命名空间
变体
操作

std::move_if_noexcept

来自 cppreference.com
< cpp‎ | utility
 
 
实用程序库
语言支持
类型支持 (基本类型, RTTI)
库功能测试宏 (C++20)
动态内存管理
程序实用程序
协程支持 (C++20)
可变参数函数
调试支持
(C++26)
三方比较
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
通用实用程序
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (在 C++20 中已弃用)
整数比较函数
(C++20)(C++20)(C++20)   
(C++20)
交换类型操作
(C++14)
(C++11)
(C++11)
(C++11)
move_if_noexcept
(C++11)
(C++17)
通用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
基本字符串转换
(C++17)
(C++17)

 
在头文件中定义 <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&&) // may throw
    {
        std::cout << "Throwing move constructor called\n";
    }
    Bad(const Bad&) // may throw as well
    {
        std::cout << "Throwing copy constructor called\n";
    }
};
 
struct Good
{
    Good() {}
    Good(Good&&) noexcept // will NOT throw
    {
        std::cout << "Non-throwing move constructor called\n";
    }
    Good(const Good&) noexcept // will NOT throw
    {
        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)
将参数转换为 xvalue
(函数模板) [编辑]