此页面中列出的具名要求,是 C++ 标准的规范性文本中使用的具名要求,用于定义标准库的期待。
某些具名要求在 C++20 中正在以概念语言特性进行形式化。在那之前,确保以满足这些要求的模板实参实例化标准库模板是程序员的重担。若不这么做,则可能导致非常复杂的编译器诊断。
全库范围的概念
operator== 是一种等价关系
C++ 具名要求: EqualityComparable类型必须能使用 == 运算符且结果应当具有标准语义。
要求
以下情况下,类型 T 满足可相等比较 (EqualityComparable) :
给定
- T或- const T类型的表达式- a、- b与- c
下列表达式必须合法且拥有其指定的效果
| 表达式 | 返回类型 | 要求 | 
|---|---|---|
| a == b | 可隐式转换为 bool | 建立一种等价关系,即满足下列性质: 
 | 
注解
为满足此要求,没有内建比较运算符的类型必须提供用户定义的 operator==。
对于既可相等比较 (EqualityComparable) 又可小于比较 (LessThanComparable) 的类型, C++ 标准库对相等(即表达式 a == b 的值)和等价(即表达式 !(a < b) && !(b < a) 的值)间做出区别。
operator< 是一种严格弱序关系
C++ 具名要求: LessThanComparable类型必须能使用 < 运算符且结果应当具有标准语义。
要求
以下情况下,类型 T 满足LessThanComparable:
给定
- T或- const T类型的表达式- a、- b与- c
下列表达式必须合法并拥有其指定的效果
| 表达式 | 返回值 | 要求 | 
|---|---|---|
| a < b | 可隐式转换为 bool | 建立严格弱序关系,即具有下列属性: 
 | 
注解
为满足此要求,没有内建比较运算符的类型必须提供用户定义的 operator<。
对于既可相等比较 (EqualityComparable) 又可小于比较 (LessThanComparable) 的类型,C++ 标准库在相等(即表达式 a == b 的值)和等价(即表达式 !(a < b) && !(b < a) 的值)间做出区别。
支持空值的指针式类型
C++ 具名要求: NullablePointer (C++11 起)指定该类型是能与 std::nullptr_t 对象进行比较的指针式类型。
要求
类型必须满足所有下列要求:
- 可相等比较 (EqualityComparable)
- 可默认构造 (DefaultConstructible)
- 可复制构造 (CopyConstructible)
- 可复制赋值 (CopyAssignable)
- 可析构 (Destructible)
此外,此类型的一个值初始化的对象必须产生该类型的空值(null)。空值必须仅与自身等价。该类型的默认初始化可拥有不确定值。
此类型必须可按语境转换成 bool。若其值等价于其空值则此转换的效果为 false,否则为 true。
此类型进行的操作均不可抛异常。
此类型必须满足下列额外的表达式,给定该类型的两个值 p 与 q,以及 np 是 std::nullptr_t 类型的值(可有 const 限定):
| 表达式 | 效果 | 
| Type p(np); Type p = np; | 之后 p等价于 nullptr。 | 
| Type(np) | 等价于 nullptr 的临时对象。 | 
| p = np | 必须返回 Type&,而且之后p等价于 nullptr。 | 
| p != q | 必须返回能按语境转换成 bool 的值。效果为 !(p == q)。 | 
| p == np np == p | 必须返回能按语境转换成 bool 的值。效果为 (p == Type())。 | 
| p != np np != p | 必须返回能按语境转换成 bool 的值。效果为 !(p == np)。 | 
注解
注意,对可空指针 (NullablePointer) 类型不要求解引用(operator* 或 operator->)。满足这些要求的最小化类型是
class handle
{int id;
public:handle(std::nullptr_t = nullptr) : id(0) { }explicit operator bool(){return id != 0;}friend bool operator ==(handle l, handle r){return l.id == r.id;}friend bool operator !=(handle l, handle r){return !(l == r);}
};
标准库
下列类型必须满足可空指针 (NullablePointer) :
- 每个分配器 (Allocator) 类型 X的成员类型X::pointer、X::const_pointer、X::void_pointer及X::const_void_pointer
- std::unique_ptr 的成员类型 X::pointer
- 类型 std::exception_ptr
调用示例
#include <iostream>
#include <string>
#include <iomanip>
#include <complex>
#include <tuple>
#include <typeinfo>struct Cell
{int x;int y;Cell() = default;Cell(int a, int b): x(a), y(b) {}//类型必须能使用 == 运算符且结果应当具有标准语义。bool operator ==(const Cell &cell) const{return x == cell.x && y == cell.y;}bool operator !=(const Cell &cell) const{// return x != cell.x && y != cell.y;return !(*this == cell);}//类型必须能使用 < 运算符且结果应当具有标准语义。bool operator <(const Cell &cell) const{if (x < cell.x){return true;}return y < cell.y;}
};class handle
{int id;
public:handle(std::nullptr_t = nullptr) : id(0) { }explicit operator bool(){return id != 0;}friend bool operator ==(handle l, handle r){return l.id == r.id;}friend bool operator !=(handle l, handle r){return !(l == r);}
};std::ostream &operator<<(std::ostream &os, const Cell &cell)
{os << "{" << cell.x << "," << cell.y << "}";return os;
}int main()
{std::cout << std::boolalpha;Cell cell1 = {101, 102};Cell cell2 = {101, 102};Cell cell3 = {201, 202};std::cout << cell1 << " == " << cell2 << "  :   "<< (cell1 == cell2) << std::endl;std::cout << cell1 << " != " << cell2 << "  :   "<< (cell1 != cell2) << std::endl;std::cout << cell1 << " == " << cell3 << "  :   "<< (cell1 == cell3) << std::endl;std::cout << cell1 << " != " << cell3 << "  :   "<< (cell1 != cell3) << std::endl;std::cout << cell1 << " <  " << cell2 << "  :   "<< (cell1 < cell2) << std::endl;std::cout << "!(" << cell1 << " <  " << cell2 << ")  :   "<< !(cell1 < cell2) << std::endl;std::cout << cell1 << " < " << cell3 << "  :   "<< (cell1 < cell3) << std::endl;std::cout << "!(" << cell1 << " < " << cell3 << ")  :   "<< !(cell1 < cell3) << std::endl;return 0;
}输出
{101,102} == {101,102}  :   true
{101,102} != {101,102}  :   false
{101,102} == {201,202}  :   false
{101,102} != {201,202}  :   true
{101,102} <  {101,102}  :   false
!({101,102} <  {101,102})  :   true
{101,102} < {201,202}  :   true
!({101,102} < {201,202})  :   false