除swap外,C++标准还期望哪些自定义函数签名承担特定任务?
C++中标准库依赖ADL的用户自定义函数
C++标准将Swappable定义为:
在
std::swap和用户自定义swap()均可见的上下文中,使用无限定函数调用swap()可交换该类型的任何左值或右值与其他类型的任何左值或右值。
此外:
许多标准库函数(例如诸多算法)要求其参数满足Swappable
这意味着,如果编写一个签名为swap(Foobar&, Foobar&)的函数,它会直接影响std::sort等标准库函数的行为——标准库会通过**无限定函数调用(依赖ADL,即参数依赖查找)**期望用户自定义函数承担特定任务。
除swap外,以下几类用户自定义函数签名也是标准库所期望的:
迭代器与范围操作类
begin/end(含cbegin/cend、rbegin/rend、crbegin/crend):标准库的范围式算法(如std::for_each、std::sort)会通过无限定调用获取自定义类型的迭代器,让自定义容器/序列能像标准容器一样被算法处理。例如为自定义的MyCollection类实现全局的begin(MyCollection&)或成员函数MyCollection::begin(),算法就能正确遍历它。size/empty:部分标准库组件(如范围适配工具、std::span构造逻辑)会通过无限定调用获取自定义容器的大小或判断是否为空,比如std::ranges::size(my_collection)会优先选用用户自定义的size函数。data:标准库会通过ADL查找data函数来获取自定义容器的底层数据指针,用于和C风格数组交互,比如std::ranges::data(my_collection)会优先调用用户实现的data函数。
比较与相等性判断运算符
operator==、operator!=、operator<、operator<=、operator>、operator>=:标准库算法(如std::equal、std::sort、std::binary_search)会依赖这些运算符的ADL查找结果。例如std::sort默认使用<进行比较,若自定义类型在自身命名空间中定义了operator<,会被优先选用而非std::less的默认实现。operator<=>(三路比较运算符):C++20引入后,标准库会通过ADL查找该运算符,用于简化比较逻辑,同时被std::compare_three_way等工具类使用。
流操作类
operator<<(流插入)、operator>>(流提取):当使用std::cout、std::cin等标准流操作自定义类型时,标准库会通过ADL查找用户实现的这两个运算符。比如std::cout << MyObj{}会匹配类型所在命名空间中定义的std::ostream& operator<<(std::ostream&, const MyObj&)。
结构化绑定与元组访问类
get:C++17及以后,若要让自定义类型支持结构化绑定,需在类型所在命名空间中实现get函数(如template<std::size_t N> auto& get(MyPair&)),标准库的结构化绑定机制会通过ADL查找该函数来访问类型的成员。
内容的提问来源于stack exchange,提问作者Drew Dormann
相关产品推荐
相关产品推荐

