Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/utility/move if noexcept"

From cppreference.com
< cpp‎ | utility
(semicolon was wrong and doesn't hurt to let copy constructor output something)
m (Shorten template names. Use {{lc}} where appropriate.)
Line 1: Line 1:
 
{{cpp/title|move_if_noexcept}}
 
{{cpp/title|move_if_noexcept}}
 
{{cpp/utility/navbar}}
 
{{cpp/utility/navbar}}
{{ddcl list begin}}
+
{{dcl begin}}
{{ddcl list header | utility}}
+
{{dcl header | utility}}
{{ddcl list item | notes={{mark since c++11}} |
+
{{dcl | notes={{mark since c++11}} |
 
template< class T >
 
template< class T >
 
typename std::conditional<   
 
typename std::conditional<   
Line 11: Line 11:
 
>::type move_if_noexcept(T& x);
 
>::type move_if_noexcept(T& x);
 
}}
 
}}
{{ddcl list end}}
+
{{dcl end}}
  
 
{{tt|move_if_noexcept}} obtains an rvalue reference to its argument if its move constructor does not throw exceptions, otherwise obtains an lvalue reference to its argument. It is typically used to combine move semantics with strong exception guarantee.
 
{{tt|move_if_noexcept}} obtains an rvalue reference to its argument if its move constructor does not throw exceptions, otherwise obtains an lvalue reference to its argument. It is typically used to combine move semantics with strong exception guarantee.
  
For example, {{c|std::vector::resize}} occasionally allocates new storage and then moves or copies elements from old storage to new storage. If an exception occurs during this operation, {{c|std::vector::resize}} undoes everything it did to this point, which is only possible if {{c|std::move_if_noexcept}} was used to decide whether to use move construction or copy construction.
+
For example, {{c|std::vector::resize}} occasionally allocates new storage and then moves or copies elements from old storage to new storage. If an exception occurs during this operation, {{c|std::vector::resize}} undoes everything it did to this point, which is only possible if {{lc|std::move_if_noexcept}} was used to decide whether to use move construction or copy construction.
  
 
===Parameters===
 
===Parameters===
{{param list begin}}
+
{{par begin}}
{{param list item | x | the object to be moved or copied}}
+
{{par | x | the object to be moved or copied}}
{{param list end}}
+
{{par end}}
  
 
===Return value===
 
===Return value===
Line 78: Line 78:
  
 
===See also===
 
===See also===
{{dcl list begin}}
+
{{dsc begin}}
{{dcl list template | cpp/utility/dcl list forward}}
+
{{dsc inc | cpp/utility/dcl list forward}}
{{dcl list template | cpp/utility/dcl list move}}
+
{{dsc inc | cpp/utility/dcl list move}}
{{dcl list end}}
+
{{dsc end}}
  
 
[[de:cpp/utility/move if noexcept]]
 
[[de:cpp/utility/move if noexcept]]

Revision as of 20:16, 31 May 2013

 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
Integer comparison functions
(C++20)(C++20)(C++20)  
(C++20)
Swap and type operations
(C++14)
(C++11)
(C++11)
(C++11)
move_if_noexcept
(C++11)
(C++17)
Common vocabulary types
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
Elementary string conversions
(C++17)
(C++17)

 
Defined in header <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);
(since C++11)

move_if_noexcept obtains an rvalue reference to its argument if its move constructor does not throw exceptions, otherwise obtains an lvalue reference to its argument. It is typically used to combine move semantics with strong exception guarantee.

For example, std::vector::resize occasionally allocates new storage and then moves or copies elements from old storage to new storage. If an exception occurs during this operation, std::vector::resize undoes everything it did to this point, which is only possible if std::move_if_noexcept was used to decide whether to use move construction or copy construction.

Contents

Parameters

x - the object to be moved or copied

Return value

std::move(x) or x, depending on exception guarantees.

Exceptions

noexcept specification:  
noexcept
  

Example

#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;
    Good g2 = std::move_if_noexcept(g);
    Bad b2 = std::move_if_noexcept(b);
}

Output:

Non-throwing move constructor called
Throwing copy constructor called

Complexity

Constant

See also

(C++11)
forwards a function argument and use the type template argument to preserve its value category
(function template) [edit]
(C++11)
converts the argument to an xvalue
(function template) [edit]