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
См. также
|
(C++11) | пересылает аргумент функции (шаблон функции) |
|
(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