为什么只需调用< std::less
(以及等效的其他函数对象)运营商,我们可以反过来运营商吗?
可能的答案有问题:
Why is std::less better than "<"?
然而,我并不完全相信(特别是关于弱排序)。有人能解释一下吗?
答案 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之类的行为比重复所有关于它如何使用<
的措辞更容易,除非它是在指针上然后它生成一个严格的弱排序,与<
一致,其中<
在标准中具有完全指定的行为。