is a header file in the C++ Standard Library. This file has two key components: , 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 . , a container template which holds two member objects ( and ) of arbitrary type(s). Additionally, the header defines default relational operators for s which have both types in common.
GCC's implementation declares the namespace in a manner similar to the following: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 <https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.4/a00897.html> namespace std::rel_ops { template <typename T> inline bool operator!=(const T& x, const T& y) { return !(x == y);
template <typename T> inline bool operator>(const T& x, const T& y) { return y < x;
template <typename T> inline bool operator<=(const T& x, const T& y) { return !(y < x);
template <typename T> inline bool operator>=(const T& x, const T& y) { return !(x < y);
Consider the following declaration of , which defines equality and less-than operators for comparison against other objects of the same type: import std;
using namespace std::rel_ops;
class BuildingLocation { unsigned int building; unsigned int room; public: bool operator==(const BuildingLocation& other) const { return (building == other.building) && (room == other.room);
bool operator<(const BuildingLocation& other) const { return (building < other.building) || (!(other.building < building) && (room < other.room));
void f1(const BuildingLocation& a1, const BuildingLocation& 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 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)
// below operator supersedes rel_ops bool operator>=(const BuildingLocation& a1, const BuildingLocation& a2) { do_something_else(); // perform some distinguishing side-effect return !(a1 < a2); // but otherwise use same procedure as rel_ops
void f2(const BuildingLocation& a1, const BuildingLocation& 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 , allowing the derivation of all relational operators from : template <typename T> inline bool operator==(const T& x, const T& y) { return !(x < y || y < x); }
is a struct that encapsulates two objects of two types. An object declared, for example, as will contain two members, and , plus three constructor functions.
The first (default) constructor initializes both members with the default values and , whereas the second one accepts one parameter of each type. The third is a template copy-constructor which will accept any , provided the types and are capable of implicit conversion to and respectively.
The implementation of std::pair<T, U> looks roughly similar to the following:Id., <https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.4/a00894.html> namespace std { template <typename T1, typename T2> struct pair { using first_type = T1; using second_type = T2; T1 first; T2 second; pair(): first(), second() {}
pair(const T1& a, const T2& b): first(a), second(b) {}
template <typename U1, typename U2> pair(const pair<U1, U2>& p): first(p.first), second(p.second) {}
Additionally this header defines all six relational operators for instances with both types in common. These define a strict weak ordering for objects of type , based on the elements and then upon the elements only when the ones are equal. namespace std { template <typename T1, typename T2> inline bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y) { return x.first == y.first && x.second == y.second;
template <typename T1, typename 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 <typename T1, typename T2> inline bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y) { return !(x == y);
template <typename T1, typename T2> inline bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y) { return y < x;
template <typename T1, typename T2> inline bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y) { return !(y < x);
template <typename T1, typename T2> inline bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y) { return !(x < y);
Additionally the header contains a template-function which deduces its return type based on parameters: namespace std { // continued from above template <typename T1, typename T2> inline pair<T1, T2> make_pair(T1 x, T2 y) { return pair<T1, T2>(x,y);
See also Relational operator
References
External links C++ reference for general utilities library