std的目的:当它刚刚调用时,更少(或类似的功能)<操作者

时间:2018-06-05 12:56:03

标签: c++ c++11

为什么只需调用< std::less(以及等效的其他函数对象)运营商,我们可以反过来运营商吗?

可能的答案有问题:

Why is std::less better than "<"?

然而,我并不完全相信(特别是关于弱排序)。有人能解释一下吗?

3 个答案:

答案 0 :(得分:7)

std::less和朋友的目的是它允许你概括你的代码。让我们说我们正在编写一个排序函数。我们从

开始
void sort(int * begin, int * end) { /* sort here using < /* }

现在我们可以对我们可以获得int*的容器进行排序。现在让我们把它变成一个模板,这样它就能用于所有类型

template<typename Iterator>
void sort(Iterator begin, Iterator end) { /* sort here using < /* }

现在我们可以对任何类型进行排序,我们使用“迭代器”作为我们的方式,说我们需要一些指向元素的东西。这一切都很好,但这意味着我们需要传递任何类型以提供operator <才能工作。它也不允许使用更改排序顺序。

现在我们可以使用函数指针,但这对内置类型不起作用,因为没有可以指向的函数。如果我们改为创建一个额外的模板参数,我们可以调用它Cmp,然后我们可以将另一个参数添加到类型Cmp的函数中。这将是比较功能。我们希望为此提供默认值,因此使用std::less可以非常轻松地为我们提供良好的“默认”行为。

所以用

之类的东西
template<typename Iterator, typename Cmp>
void sort(Iterator begin, Iterator end, 
          Cmp c = std::less<typename std::iterator_traits<Iterator>::value_type>) 
          { /* sort here using c /* } 

它允许您对所有内置类型(任何具有operator <的类型)进行排序,并允许您指定任何其他方式来比较数据中的元素以对其进行排序。

这就是我们需要std::less和朋友的原因。它让我们使代码具有通用性和灵活性,而无需编写大量的锅炉板。

使用函数对象也为我们带来了一些性能优势。如果使用函数指针,编译器更容易内联对函数调用操作符的调用。它还允许比较器具有状态,就像它被调用的次数一样。要更深入地了解这一点,请参阅C++ Functors - and their uses

答案 1 :(得分:1)

using DifferentialEquations using Plots a = 0.02 b = 0.2 c = -65 d = 8 i = 0 p = [a,b,c,d,i] function fun(du,u,p,t) if u[1] <30 du[1] = (0.04*u[1] + 5)*u[1] + 150 - u[2] - p[5] du[2] = p[1]*(p[2]*u[1]-u[2]) else u[1] = p[3] u[2] = u[2] + p[4] end end u0 = [0.0;0.0] tspan = (0.0,100) prob = ODEProblem(fun,u0,tspan,p) tic() sol = solve(prob,reltol = 1e-8) toc() plot(sol) 只是一个默认策略,它采用对象的自然排序顺序(即其比较运算符)。

使用std::less作为默认模板参数的好处是,您可以调整排序算法(或您的有序数据结构),以便您可以决定是否使用自然排序顺序(例如,自然数中的次要到主要)或特定问题的不同排序顺序(例如,第一个奇数,然后是偶数),而不修改实际的对象运算符或算法本身。

std::less

输出:

struct natural {
   unsigned value;

   natural( unsigned v ) :
     value(v)
   {
   }

   bool operator< ( natural other ) const {
      return value < other.value;
   }
};

struct first_the_odds {
   bool operator()( natural left, natural right ) const {
      bool left_odd  = left.value % 2 != 0;
      bool right_odd = right.value % 2 != 0;

      if( left_odd == right_odd ) {
         return left < right;
      } else {
         return left_odd;
      }
   }
};

// Sort me some numbers
std::vector<natural> numbers = { 0, 1, 2, 3, 4 };
std::sort( numbers.begin(), numbers.end(), first_the_odds() );
for( natural n : numbers )
   std::cout << n.value << ",";

答案 2 :(得分:1)

<的第一个问题是,根据C ++标准,指针上的<对任何不指向同一个父母的内容都是完全无稽之谈。对象或数组。

这是因为存在分段存储模型,如8086。通过忽略段号在段内进行比较要快得多,并且对象不能跨越段;因此<只能比较细分中的偏移并忽略细分数。

在同样奇怪的硬件上还会出现这样的其他情况;想象一下硬件,其中const(ROM)和非const(RAM)数据存在于一个单独的存储空间中。

尽管存储器架构中存在任何怪癖,

std::less<Pointer>同时保证了严格的弱序。它将为每次比较付出代价。

我们需要std::less的第二个原因是能够传递&#34;小于&#34;的概念。围绕easiliy。查看std::sort的3个参数重载:

void sort( Iterator, Iterator, Comparator )

这里我们可以传递我们想要在第3个参数中排序的方式。如果我们通过std::greater<Foo>{},我们会得到一种,如果我们通过std::less<Foo>{},我们就会相反。

默认情况下,2参数版本的排序类似于std::less,但是一旦你有更大,更大的相等,更少相等,添加更少只是有意义。

一旦你定义了更少,用它来描述默认std sort和std map之类的行为比重复所有关于它如何使用<的措辞更容易,除非它是在指针上然后它生成一个严格的弱排序,与<一致,其中<在标准中具有完全指定的行为。