<utility> in C++
Last Updated :
25 Dec, 2023
It is a header file that contains utilities in unrelated domains.
- Pairs: These are the objects which can hold two different types of values.
- Generic Relational Approach: It is used for the relational operators !=, >, = under a specific namespace: rel_ops.
- Generic swap function: This a standard definition used by default by the components of the standard library for all types that do not provide their own overload: swap.
Functions:
1. swap: It exchanges the value of two objects.
C++
#include <iostream>
#include <utility>
using namespace std;
int main()
{
int a[4];
int b[] = { 10, 20, 30, 40 };
swap(a, b);
cout << "a contains:" ;
for ( int i = 0; i < 4; i++)
cout << a[i] << endl;
return 0;
}
|
Output
a contains:10
20
30
40
2. make_pair: It constructs a pair with its first element set to x and its second element set to y.
C++
#include <iostream>
#include <utility>
using namespace std;
int main()
{
pair< int , int > a;
pair< int , char > b;
a = make_pair(10, 20);
b = make_pair(15.5, 'B' );
cout << "a: " << a.first << ", " << a.second << endl;
cout << "b: " << b.first << ", " << b.second << endl;
return 0;
}
|
Output
a: 10, 20
b: 15, B
3. move: It moves as rvalue. move is used to indicate that an object may be “moved from”, i.e. allowing the transfer of resources from an object(to be moved) to another object.
C++
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using namespace std;
int main()
{
string s = "Hello!!" ;
string s1 = "I am a geek." ;
vector<string> gfg;
gfg.push_back(s);
gfg.push_back(move(s1));
cout << "gfg contains:" ;
for ( int i = 0; i < gfg.size(); i++)
cout << ' ' << gfg[i];
cout << endl;
return 0;
}
|
Output
gfg contains: Hello!! I am a geek.
4. move (range of elements): It moves the elements in the range [first, last) into the range beginning at result.
After this operation the elements in the moved-from range will still contain valid values of the appropriate type, but not necessarily the same values as before the move.
C++
#include <iostream>
#include <algorithm>
#include <string>
#include <utility>
#include <vector>
using namespace std;
int main()
{
vector<string> string1
= { "Hello!" , "I" , "am" , "a" , "geek" };
vector<string> string2(5);
cout << "Moving ranges...\n" ;
move(string1.begin(), string1.begin() + 5,
string2.begin());
cout << "string1 contains " << string1.size()
<< " elements\n" ;
cout << "string2 contains " << string2.size()
<< " elements(after moving):" ;
for ( int i = 0; i < string2.size(); i++)
cout << string2[i] << " " ;
cout << endl;
return 0;
}
|
Output
Moving ranges...
string1 contains 5 elements
string2 contains 5 elements(after moving):Hello! I am a geek
5. move_if_noexcept: It obtains an rvalue reference to its argument if its move constructor does not throw exceptions, otherwise obtains an lvalue reference to its argument.
C++
#include <iostream>
#include <utility>
using namespace std;
struct Bad {
Bad() {}
Bad(Bad&&)
{
cout << "Throwing move constructor called" << endl;
}
Bad( const Bad&)
{
cout << "Throwing copy constructor called" << endl;
}
};
struct Good {
Good() {}
Good(Good&&) noexcept
{
cout << "Non-throwing move constructor called"
<< endl;
}
Good( const Good&) noexcept
{
cout << "Non-throwing copy constructor called"
<< endl;
}
};
int main()
{
Good g;
Bad b;
Good g2 = move_if_noexcept(g);
Bad b2 = move_if_noexcept(b);
}
|
Output
Non-throwing move constructor called
Throwing copy constructor called
6. decval: It returns an rvalue reference without referring to any object.
This function selects the type of an argument as an rvalue reference if its move constructor never throw, or alternatively, as an lvalue reference if the type is copy-constructible. If the type is neither, the function returns an rvalue, which will be selected for move-only types (even if they may throw).
Some operations can be implemented both by moving or by copying objects, generally moving for rvalues and copying for lvalues: Moving is generally a more efficient operation than copying when the object is no longer needed (such as rvalues).
C++
#include <iostream>
#include <utility>
using namespace std;
struct A {
virtual int value() = 0;
};
class B : public A {
int val_;
public :
B( int i, int j)
: val_(i * j)
{
}
int value() { return val_; }
};
int main()
{
decltype (declval<A>().value()) a;
decltype (declval<B>().value()) b;
a = b = B(100, 20).value();
cout << a << endl;
return 0;
}
|
Share your thoughts in the comments
Please Login to comment...