Namespaces
Variants

std:: move_if_noexcept

From cppreference.net
Utilities library
Определено в заголовке <utility>
template < class T >
/* see below */ move_if_noexcept ( T & x ) noexcept ;
(начиная с C++11)
(constexpr начиная с C++14)

std::move_if_noexcept получает rvalue-ссылку на свой аргумент, если его конструктор перемещения не генерирует исключения или если отсутствует конструктор копирования (тип только для перемещения), в противном случае получает lvalue-ссылку на свой аргумент. Обычно используется для совмещения семантики перемещения с строгой гарантией исключений.

Возвращаемый тип 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)
преобразует аргумент в xvalue
(шаблон функции)