为什么 std::less 是一个函子

why is std::less a functor?

本文关键字:一个 std less 为什么      更新时间:2023-10-16

为什么少了一个函子,而不是像下面myless这样的模板化函数?为什么委员会决定这样做,我可以去哪里进一步阅读?C++11标准是否解释了委员会做出某些决定的原因?

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#if 1
template <class T> struct stdless {
  bool operator() (const T& x, const T& y) const {return x<y;}
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};
#else
    #define stdless std::less
#endif
//bool myless(int a, int b) { return a<b; }
template<class T>
bool myless(T a, T b) { return a<b; }
int main()
{
    vector<int> a{5, 3, 1,6};
    myless(5, 6);
    stdless<int>()(5, 6);
    auto fn1=stdless<int>();
    fn1(5,9);
    auto fn2=myless<int>;
    fn2(5,9);
    sort(a.begin(), a.end(), myless<int>);
    sort(a.begin(), a.end(), less<int>());
    for(auto b=a.begin(); b!=a.end(); ++b)
        cout << *b<<endl;
}

这有不同的原因。第一个是,编译器在函子上内联对operator()的调用比通过指向函数的指针内联调用更容易(当执行调用的代码本身未内联时)。

除了这种性能优势之外,对于std::less<>函子的不同用途,手头还有更大的设计考虑因素。特别要考虑任何已分类的容器,例如 std::set<T,Comparator> 。你不能将指针直接作为类型传递函数,所以为了能够使用你的myless集合的定义必须std::set<T,bool (*)(T,T)>,现在这里的下一个问题是指针没有明智的默认构造函数来做你想要的,所以用户代码必须在容器的构造上提供函数指针, 这是潜在的错误。

std::set<int, bool(*)(int,int)> s(&myless);

忘记传递函数指针(std::set<int,bool(*)(int,int)> s;)很简单,这会让你得到错误的指针并导致未定义的行为。在函子的情况下,这不是问题,编译器将默认构造比较器成员,这将是一个有效的对象。

相关文章: