Top Qs
Timeline
Chat
Perspective

Utility (C++)

From Wikipedia, the free encyclopedia

Remove ads

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

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

Remove ads

rel_ops

Summarize
Perspective

GCC's implementation declares the rel_ops namespace (nested within namespace std) in the following manner:[1]

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

Consider the following declaration of 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 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)
#include <utility>
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 rel_ops, allowing the derivation of all relational operators from <:

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

pair

Summarize
Perspective

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

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

GCC's implementation defines the pair mechanism as follows.[2]

template<class _T1, class _T2> 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<class _U1, class _U2> pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) { }
	};

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

// continued from above

template<class _T1, class _T2> inline bool operator ==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
	{ return __x.first == __y.first && __x.second == __y.second; }
template<class _T1, class _T2> 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<class _T1, class _T2> inline bool operator !=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
	{ return !(__x == __y); }
template<class _T1, class _T2> inline bool operator >(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
	{ return __y < __x; }
template<class _T1, class _T2> inline bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
	{ return !(__y < __x); }
template<class _T1, class _T2> inline bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
	{ return !(__x < __y); }

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

// continued from above
template<class _T1, class _T2> inline pair<_T1, _T2> make_pair(_T1 __x, _T2 __y)
	{ return pair<_T1, _T2>(__x, __y); }
Remove ads

See also

References

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads