Spec-Zone.ru › C++

std::move_if_noexcept

Определено в заголовке <utility>
template< class T >
typename std::conditional<  
    !std::is_nothrow_move_constructible<T>::value && std::is_copy_constructible<T>::value,
    const T&,
    T&& 
>::type move_if_noexcept( T& x ) noexcept;
(с C++11)
(до C++14)
template< class T >
constexpr typename std::conditional<  
    !std::is_nothrow_move_constructible<T>::value && std::is_copy_constructible<T>::value,
    const T&,
    T&& 
>::type move_if_noexcept( T& x ) noexcept;
(с C++14)

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

Параметры

x - объект, который нужно переместить или скопировать

Возвращаемое значение

Ссылка типа rvalue или lvalue, в зависимости от гарантии отсутствия исключений.

Сложность

Постоянная.

Примечания

Она используется, например, в 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

См. также

forward
(C++11)
пересылает аргумент функции
(шаблон функции)
move
(C++11)
получает ссылку типа rvalue
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/utility/move_if_noexcept

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API