简体   繁体   English

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

[英]why is std::less a functor?

Why is less a functor rather then a templated function like myless below?为什么 less 是一个函子而不是像下面的 myless 这样的模板化函数? Why did the committee decide on that and where can I go for further reading?为什么委员会会做出这样的决定,我可以去哪里进一步阅读? Also does the C++11 standard explain why the committee made certain decisions? 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;
}

There are different reasons for that.这有不同的原因。 The first one, is that it is easier for the compiler to inline the call to operator() on a functor than to inline a call through a pointer to function (when the code doing the call is not inlined itself).第一个是编译器在函子上内联对operator()的调用比通过指向函数的指针内联调用(当执行调用的代码本身没有内联时)更容易。

Beyond that performance advantage, there are bigger design considerations at hand with different uses of the std::less<> functor.除了性能优势之外,还有更大的设计考虑因素,包括std::less<>函子的不同用途。 In particular consider any of the sorted containers, like std::set<T,Comparator> .特别考虑任何已排序的容器,例如std::set<T,Comparator> You cannot pass a pointer to function directly as a type, so to be able to use your myless the definition of the set would have to be std::set<T,bool (*)(T,T)> , now the next problem here is that pointers don't have sensible default constructor that would do what you want, so user code must provide the function pointer on construction of the container, which is a potential for errors.您不能将指针直接作为类型传递给函数,因此为了能够使用myless ,集合的定义必须是std::set<T,bool (*)(T,T)> ,现在是下一个这里的问题是指针没有合理的默认构造函数来执行您想要的操作,因此用户代码必须在构造容器时提供函数指针,这可能会导致错误。

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

It is simple to just forget to pass the function pointer ( std::set<int,bool(*)(int,int)> s; ) and that will get you the wrong pointer and cause undefined behavior.忘记传递函数指针( std::set<int,bool(*)(int,int)> s; )很简单,这会让你得到错误的指针并导致未定义的行为。 In the case of a functor this is not a problem, the compiler will default construct the comparator member and that will be a valid object.在函子的情况下,这不是问题,编译器将默认构造比较器成员,这将是一个有效的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM