Utility (C++)

{{Orphan|date=July 2016}}

{{Use dmy dates|date=February 2021}}

{{C++ Standard library}}

{{lowercase}}

{{code|utility}} is a header file in the C++ Standard Library. This file has two key components:

  • {{code|rel_ops}}, a namespace containing set of templates which define default behavior for the relational operators {{code|1=!=}}, {{code|1=>}}, {{code|1=<=}}, and {{code|1=>=}} between objects of the same type, based on user-defined operators {{code|1===}} and {{code|1=<}}.
  • {{code|pair}}, a container template which holds two member objects ({{code|first}} and {{code|second}}) of arbitrary type(s). Additionally, the header defines default relational operators for {{code|pair}}s which have both types in common.

rel_ops

GCC's implementation declares the {{code|rel_ops}} namespace (nested within {{cpp|namespace std}}) in the following manner:Copyright (C) 2001, 2002, 2004, 2005, 2008 Free Software Foundation, Inc.; available under the GNU General Public License, version 3 and later. Documentation available online at

namespace rel_ops {

template inline bool operator !=(const _Tp& __x, const _Tp& __y) { return !(__x == __y); }

template inline bool operator >(const _Tp& __x, const _Tp& __y) { return __y < __x; }

template inline bool operator <=(const _Tp& __x, const _Tp& __y) { return !(__y < __x); }

template inline bool operator >=(const _Tp& __x, const _Tp& __y) { return !(__x < __y); }

}

Consider the following declaration of {{code|class A}}, which defines equality and less-than operators for comparison against other objects of the same type:

class A {

int building;

int room;

public:

bool operator ==(const A& other) const {

return (building == other.building) && (room == other.room);

}

bool operator <(const A& other) const {

return (building < other.building) ||

(!(other.building < building) && (room < other.room));

}

};

void f1(const A& a1, const A& a2) {

bool equal = (a1 == a2); // uses == defined within class A

bool not_equal = (a1 != a2); // error: no match for ‘operator!=’ in ‘a1 != a2’

bool less = (a1 < a2); // uses < defined within class A

bool greater = (a1 > a2); // error: no match for ‘operator >’ in ‘a1 > a2’

bool less_equal = (a1 <= a2); // error: no match for ‘operator<=’ in ‘a1 <= a2’

bool greater_equal = (a1 >= a2); // error: no match for ‘operator>=’ in ‘a1 >= a2’

}

By invoking the {{code|rel_ops}} templates, one can assign a default meaning to the remaining relational operators. However, if a similar type-specific (i.e. non-template) operator exists in the current scope, even outside the class definition, the compiler will prefer it instead.

// (continued from above)

  1. include

using namespace std::rel_ops;

// below operator supersedes rel_ops

bool operator >=(const A& a1, const A& a2) {

do_something_else(); // perform some distinguishing side-effect

return !(a1 < a2); // but otherwise use same procedure as rel_ops

};

void f2(const A& a1, const A& a2) {

bool equal = (a1 == a2); // uses operator == defined within class A

bool not_equal = (a1 != a2); // uses !(a1 == a2) per rel_ops

bool less = (a1 < a2); // uses operator < defined within class A

bool greater = (a1 > a2); // uses (a2 < a1) per rel_ops

bool less_equal = (a1 <= a2); // uses !(a2 < a1) per rel_ops

bool greater_equal = (a1 >= a2); // uses global operator >= defined above

}

One could of course declare the following in tandem with {{code|rel_ops}}, allowing the derivation of all relational operators from {{code|<}}:

template inline bool operator ==(const _Tp& __x, const _Tp& __y) { return !(__x < __y || __y < __x); }

pair

An object declared, for example, as {{cpp|std::pair}} will contain two members, {{cpp|int first;}} and {{cpp|float second;}}, plus three constructor functions.

The first (default) constructor initializes both members with the default values {{cpp|0}} and {{cpp|0.0}}, whereas the second one accepts one parameter of each type. The third is a template copy-constructor which will accept any {{cpp|std::pair<_U1, _U2>}}, provided the types {{cpp|_U1}} and {{cpp|_U2}} are capable of implicit conversion to {{cpp|int}} and {{cpp|float}} respectively.

GCC's implementation defines the {{code|pair}} mechanism as follows.Id.,

template struct pair {

typedef _T1 first_type;

typedef _T2 second_type;

_T1 first;

_T2 second;

pair(): first(), second() { }

pair(const _T1& __a, const _T2& __b): first(__a), second(__b) { }

template pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) { }

};

Additionally this header defines all six relational operators for {{code|pair}} instances with both types in common. These define a strict weak ordering for objects of type {{cpp|std::pair<_T1, _T2>}}, based on the {{code|first}} elements and then upon the {{code|second}} elements only when the {{code|first}} ones are equal.

// continued from above

template inline bool operator ==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)

{ return __x.first == __y.first && __x.second == __y.second; }

template inline bool operator <(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)

{ return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second); }

template inline bool operator !=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)

{ return !(__x == __y); }

template inline bool operator >(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)

{ return __y < __x; }

template inline bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)

{ return !(__y < __x); }

template inline bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)

{ return !(__x < __y); }

Additionally the header contains a template-function {{code|make_pair()}} which deduces its return type based on parameters:

// continued from above

template inline pair<_T1, _T2> make_pair(_T1 __x, _T2 __y)

{ return pair<_T1, _T2>(__x, __y); }

See also

References

{{reflist}}

  • {{cite book

| url = http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf

| title=ISO/IEC 14882:2011 draft specification

| at=p. 508, § 20

}}