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:
std::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<.std::pair<T, U>, a container template which holds two member objects (firstandsecond) of arbitrary type(s). Additionally, the header defines default relational operators forpairs which have both types in common.
Remove ads
.mw-parser-output .monospaced{font-family:monospace,monospace}std::rel_ops
Summarize
Perspective
GCC's implementation declares the std::rel_ops namespace in a manner similar to the following:[1]
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 class BuildingLocation, 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 std::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)
// 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 rel_ops, 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);
}
Remove ads
std::pair
Summarize
Perspective
std::pair<T1, T2> is a struct that encapsulates two objects of two types. 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.
The implementation of std::pair<T, U> looks roughly similar to the following:[2]
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 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.
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 make_pair() 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);
}
}
Remove ads
See also
References
External links
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads