本文主要是介绍C++ 具名要求-全库范围的概念,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
此页面中列出的具名要求,是 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
这篇关于C++ 具名要求-全库范围的概念的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!