<utility> functions
The latest version of this topic can be found at <utility> functions.
exchange | forward | get |
make_pair | move | swap |
exchange
(C++14) Assigns a new value to an object and returns its old value.
template <class T, class Other = T>
T exchange(T& val, Other&& new_val)
Parameters
val
The object that will receive the value of new_val.
new_val
The object whose value is copied or moved into val.
Remarks
For complex types, exchange
avoids copying the old value when a move constructor is available, avoids copying the new value if it’s a temporary object or is moved, and accepts any type as the new value, using any available converting assignment operator. The exchange function is different from std::swap in that the left argument is not moved or copied to the right argument.
Example
The following example shows how to use exchange
. In the real world, exchange
is most useful with large objects that are expensive to copy:
#include <utility>
#include <iostream>
using namespace std;
struct C
{
int i;
//...
};
int main()
{
// Use brace initialization
C c1{ 1 };
C c2{ 2 };
C result = exchange(c1, c2);
cout << "The old value of c1 is: " << result.i << endl;
cout << "The new value of c1 after exchange is: " << c1.i << endl;
return 0;
}
/* Output:
The old value of c1 is: 1
The new value of c1 after exchange is: 2
*/
forward
Conditionally casts its argument to an rvalue reference if the argument is an rvalue or rvalue reference. This restores the rvalue-ness of an argument to the forwarding function in support of perfect forwarding.
template <class Type> // accepts lvalues
constexpr Type&& forward(typename remove_reference<Type>::type& Arg) noexcept
template <class Type> // accepts everything else
constexpr Type&& forward(typename remove_reference<Type>::type&& Arg) noexcept
Parameters
Parameter | Description |
---|---|
Type |
The type of the value passed in Arg , which might be different than the type of Arg . Typically determined by a template argument of the forwarding function. |
Arg |
The argument to cast. |
Return Value
Returns an rvalue reference to Arg
if the value passed in Arg
was originally an rvalue or a reference to an rvalue; otherwise, returns Arg
without modifying its type.
Remarks
You must specify an explicit template argument to call forward
.
forward
does not forward its argument. Instead, by conditionally casting its argument to an rvalue reference if it was originally an rvalue or rvalue reference, forward
enables the compiler to perform overload resolution with knowledge of the forwarded argument's original type. The apparent type of an argument to a forwarding function might be different than its original type—for example, when an rvalue is used as an argument to a function and is bound to a parameter name; having a name makes it an lvalue, regardless of whether the value actually exists as an rvalue— forward
restores the rvalue-ness of the argument.
Restoring the rvalue-ness of an argument's original value in order to perform overload resolution is known as perfect forwarding. Perfect forwarding enables a template function to accept an argument of either reference type and to restore its rvalue-ness when it's necessary for correct overload resolution. By using perfect forwarding, you can preserve move semantics for rvalues and avoid having to provide overloads for functions that vary only by the reference type of their arguments.
get
Gets an element from a pair
object by index position, or by type.
// get reference to element at Index in pair Pr
template <size_t Index, class T1, class T2>
constexpr tuple_element_t<Index, pair<T1, T2>>&
get(pair<T1, T2>& Pr) noexcept;
// get reference to element T1 in pair Pr
template <class T1, class T2>
constexpr T1& get(pair<T1, T2>& Pr) noexcept;
// get reference to element T2 in pair Pr
template <class T2, class T1>
constexpr T2& get(pair<T1, T2>& Pr) noexcept;
// get const reference to element at Index in pair Pr
template <size_t Index, class T1, class T2>
constexpr const tuple_element_t<Index, pair<T1, T2>>&
get(const pair<T1, T2>& Pr) noexcept;
// get const reference to element T1 in pair Pr
template <class T1, class T2>
constexpr const T1& get(const pair<T1, T2>& Pr) noexcept;
// get const reference to element T2 in pair Pr
template <class T2, class T1>
constexpr const T2& get(const pair<T1, T2>& Pr) noexcept;
// get rvalue reference to element at Index in pair Pr
template <size_t Index, class T1, class T2>
constexpr tuple_element_t<Index, pair<T1, T2>>&&
get(pair<T1, T2>&& Pr) noexcept;
// get rvalue reference to element T1 in pair Pr
template <class T1, class T2>
constexpr T1&& get(pair<T1, T2>&& Pr) noexcept;
// get rvalue reference to element T2 in pair Pr
template <class T2, class T1>
constexpr T2&& get(pair<T1, T2>&& Pr) noexcept;
Parameters
Index
The 0-based index of the designated element.
T1
The type of the first pair element.
T2
The type of the second pair element.
pr
The pair to select from.
Remarks
The template functions each return a reference to an element of its pair
argument.
For the indexed overloads, if the value of Index
is 0 the functions return pr.first
and if the value of Index
is 1 the functions return pr.second
. The type RI
is the type of the returned element.
For the overloads that do not have an Index parameter, the element to return is deduced by the type argument. Calling get<T>(Tuple)
will produce a compiler error if pr
contains more or less than one element of type T.
Example
#include <utility>
#include <iostream>
using namespace std;
int main()
{
typedef pair<int, double> MyPair;
MyPair c0(9, 3.14);
// get elements by index
cout << " " << get<0>(c0);
cout << " " << get<1>(c0) << endl;
// get elements by type (C++14)
MyPair c1(1, 0.27);
cout << " " << get<int>(c1);
cout << " " << get<double>(c1) << endl;
/*
Output:
9 3.14
1 0.27
*/
}
make_pair
A template function that you can use to construct objects of type pair
, where the component types are automatically chosen based on the data types that are passed as parameters.
template <class T, class U>
pair<T, U>
make_pair(T& Val1, U& Val2);
template <class T, class U>
pair<T, U>
make_pair(T& Val1, U&& Val2);
template <class T, class U>
pair<T, U>
make_pair(T&& Val1, U& Val2);
template <class T, class U>
pair<T, U>
make_pair(T&& Val1, U&& Val2);
Parameters
Val1
Value that initializes the first element of pair
.
Val2
Value that initializes the second element of pair
.
Return Value
The pair object that's constructed: pair
< T
, U
>( Val1
, Val2
).
Remarks
make_pair
converts object of type reference_wrapper Class to reference types and converts decaying arrays and functions to pointers.
In the returned pair
object, T
is determined as follows:
If the input type
T
isreference_wrapper<X>
, the returned typeT
isX&
.Otherwise, the returned type
T
isdecay<T>::type
. If decay Class is not supported, the returned typeT
is the same as the input typeT
.
The returned type U
is similarly determined from the input type U
.
One advantage of make_pair
is that the types of objects that are being stored are determined automatically by the compiler and do not have to be explicitly specified. Don't use explicit template arguments such as make_pair<int, int>(1, 2)
when you use make_pair
because it is unnecessarily verbose and adds complex rvalue reference problems that might cause compilation failure. For this example, the correct syntax would be make_pair(1, 2)
The make_pair
helper function also makes it possible to pass two values to a function that requires a pair as an input parameter.
Example
For an example about how to use the helper function make_pair
to declare and initialize a pair, see pair Structure.
move
Unconditionally casts its argument to an rvalue reference, and thereby signals that it can be moved if its type is move-enabled.
template <class Type>
constexpr typename remove_reference<Type>::type&& move(Type&& Arg) noexcept;
Parameters
Parameter | Description |
---|---|
Type |
A type deduced from the type of the argument passed in Arg , together with the reference collapsing rules. |
Arg |
The argument to cast. Although the type of Arg appears to be specified as an rvalue reference, move also accepts lvalue arguments because lvalue references can bind to rvalue references. |
Return Value
Arg
as an rvalue reference, whether or not its type is a reference type.
Remarks
The template argument Type
is not intended to be specified explicitly, but to be deduced from the type of the value passed in Arg
. The type of Type
is further adjusted according to the reference collapsing rules.
move
does not move its argument. Instead, by unconditionally casting its argument—which might be an lvalue—to an rvalue reference, it enables the compiler to subsequently move, rather than copy, the value passed in Arg
if its type is move-enabled. If its type is not move-enabled, it is copied instead.
If the value passed in Arg
is an lvalue—that is, it has a name or its address can be taken—it's invalidated when the move occurs. Do not refer to the value passed in Arg
by its name or address after it's been moved.
swap
Exchanges the elements of two pair Structure objects.
template <class T, class U>
void swap(pair<T, U>& left, pair<T, U>& right);
Parameters
Parameter | Description |
---|---|
left |
An object of type pair . |
right |
An object of type pair . |
Remarks
One advantage of swap
is that the types of objects that are being stored are determined automatically by the compiler and do not have to be explicitly specified. Don't use explicit template arguments such as swap<int, int>(1, 2)
when you use swap
because it is unnecessarily verbose and adds complex rvalue reference problems that might cause compilation failure.