为什么没有std :: less函子? [英] why is std::less a functor?

查看:48
本文介绍了为什么没有std :: less函子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么下面的函数不是函子,而是像myless这样的模板化函数?委员会为何对此做出决定,我在哪里可以继续阅读?C ++ 11标准也解释了委员会为何做出某些决定的原因吗?

Why is less a functor rather then a templated function like myless below? 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?

#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()的调用比通过函数指针内联的调用(当未内联执行调用的代码内联时)更容易.本身.)

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).

除了性能优势之外, std :: less<<> 函子的不同用法还有很多更大的设计考虑因素.特别要考虑任何已排序的容器,例如 std :: set< T,Comparator> .您不能将指针直接传递为类型,因此要使用您的 myless ,该集合的定义必须为 std :: set< T,bool(*)(T,T)> ,现在这里的下一个问题是指针没有明智的 default 构造函数来执行您想要的操作,因此用户代码必须在其上提供函数指针容器的构造,这有可能导致错误.

Beyond that performance advantage, there are bigger design considerations at hand with different uses of the std::less<> functor. In particular consider any of the sorted containers, like 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.

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

简单地忘记传递函数指针( std :: set< int,bool(*)(int,int)> s; )会很容易使您出错指针,并导致未定义的行为.对于函子来说,这不是问题,编译器将默认构造比较器成员,这将是一个有效的对象.

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. 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.

这篇关于为什么没有std :: less函子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆