Namespaces
Variants

std::move_if_noexcept

Со ru.cppreference.net
 
 
Библиотека утилит
Поддержка языка
Поддержка типов (базовые типы, RTTI)
Макросы тестирования возможностей библиотеки (C++20)
Утилиты программ
Вариативные функции
Поддержка корутин (C++20)
Поддержка контрактов (C++26)
Трёхстороннее сравнение
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Общие утилиты
Операторы отношений (устарело в C++20)
 
Определён в заголовке <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:

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