预定义函子用作 C++ 中运算符的包装器,例如在 STL 算法中使用。除了条件运算符之外,似乎所有运算符都有一个包装器。是不是失踪了?如果是,为什么?
以下是此类函子与
std::tansform
算法的潜在用途
#include <algorithm>
#include <iostream>
#include <vector>
#include <ctime>
int main() {
std::vector<int> v1(10), v2(10), v3(10);
srand(static_cast<unsigned>(time(nullptr)));
// generates random values in two vectors
generate(v1.begin(), v1.end(), []{return rand()%100;});
generate(v2.begin(), v2.end(), []{return rand()%100;});
// selects the larger element out of corresponding two
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(),
[](int i, int j){ if (i>j) return i; else return j;});
// equivalent code with potential conditional functor
// transform(v1.begin(), v1.end(), v2.begin(), v3.begin(),
// conditional<>(greater<>)());
// prints the selected values
for(auto e: v3) std::cout << e << ", "; std::cout << endl;
}
除了条件运算符之外,似乎所有运算符都有一个包装器。是不是不见了?
是的,它不见了。不,它不是唯一失踪的一个。也没有用于(前/后)递增、(前/后)递减、下标、间接、成员访问和逗号运算符的包装器。也是操作者的地址,除非你算
std::addressof
(不受operator&
影响)。
如果是,为什么?
原因之一是它不是算术或逻辑运算符。根据 cppreference.com,运算符函数对象用于“常见算术和逻辑运算”(加上函数调用运算符,前面在链接页面上提到过)。
另一个原因是与标准算法的链接很弱。算术运算符直接变换其参数。逻辑运算符直接比较它们的参数。相反,使用比较运算符的示例是间接的,因为参数除了用作操作数之外还必须经过其他操作(
std::greater
)。您偏离直接包装器越多,您的实现就越有可能不符合要求。
离开您的具体示例,为什么此设置应被视为等同于“比较运算符”就变得不太清楚了。一般来说,第一个操作数(布尔条件)不必依赖于其他两个操作数,因此您提出的方法更多的是比较运算符的专业化,而不是它的包装器。另外,这种专门化的用处有限,因为它无法转换参数,只能选择其中之一。将运算符包装在 lambda 中会更强大。对于定义和实现这个专用包装器的成本来说,这里并没有太多好处。