C++ utility move_if_noexcept 函数

  • 定义和用法

    template <class T>
      typename conditional < is_nothrow_move_constructible<T>::value ||
                             !is_copy_constructible<T>::value,
                             T&&, const T& >::type move_if_noexcept(T& arg) noexcept;
    std::move_if_noexcept 返回对arg的右值引用,除非复制比提供至少一个强力的异常保证更好。 这些操作提供了有力的保证,可以保证在发生异常的情况下,对象保持与操作前相同的状态。这可以通过对副本进行操作(以使原始对象在操作过程中保持完整)或仅使用不抛出的操作(在这种情况下,提供更高级别的保证:nothrow guarantee)来实现。某些操作可以通过移动或复制对象来实现,通常针对右值移动并针对右值:与不再需要对象(例如rvalues)时进行复制相比,移动通常比复制更为有效。如果该类型不是可移动构造的(即其移动构造函数从不抛出),则该函数选择参数的类型作为右值引用;如果该类型是可复制构造的,则该函数选择作为左值引用。如果类型都不是,则该函数返回一个rvalue,它将为仅移动类型选择(即使它们可能会抛出)。 该函数返回,但返回类型强制转换为或move(arg)T&&const T&,具体取决于 T。
  • 参数

    arg
    一个对象。
  • 返回值

    如果T不可移动构造或T不可复制构造,则引用arg的右值引用。否则为左值引用。返回类型使用条件语句在两种类型之间进行选择:T&&和const T&。
  • 示例

    
    // move_if_noexcept example
    #include <utility>      // std::move_if_noexcept
    #include <iostream>     // std::cout
    
    // function with lvalue and rvalue reference overloads:
    template <class T> void overloaded (T&  x) {std::cout << "[lvalue]\n";}
    template <class T> void overloaded (T&& x) {std::cout << "[rvalue]\n";}
    
    struct A {   // copyable + moveable (noexcept)
      A() noexcept {}
      A (const A&) noexcept {}
      A (A&&) noexcept {}
    };
    
    struct B {   // copyable + moveable (no noexcept)
      B() {}
      B (const B&) {}
      B (B&&) {}
    };
    
    struct C {   // moveable only (no noexcept)
      C() {}
      C (C&&) {}
    };
    
    int main () {
            A a = A();
            B b = B();
            C c = C();
      std::cout << "A: "; overloaded (std::move_if_noexcept(a));
      std::cout << "B: "; overloaded (std::move_if_noexcept(b));
      std::cout << "C: "; overloaded (std::move_if_noexcept(c));
      return 0;
    }
    
    尝试一下
    输出
    
    A: [rvalue]
    B: [lvalue]
    C: [rvalue]
    
  • 数据竞争

    调用此函数不会引起任何数据争用。尽管注意到将返回的值传递给实现移动语义的函数通常涉及修改对象的值或有效性。
  • 异常安全

    这函数不会抛出异常。
  • 相关页面

    forward 转发参数(函数模板)
    move 作为右值移动(函数模板)