![](/img/trans.png)
[英]What is the purpose of std::ostream& out for this friend overloaded operator function and not just std::cout?
[英]Purpose of having std:less (or similar function) while it just call < operator
为什么std::less
(和等效的其他函数对象)只需要调用<运算符,我们可以反过来运算符?
可能的答案有问题:
但是我并不完全相信(特别是关于弱排序)。 有人可以解释一下吗?
std::less
和friends的目的是它允许你概括你的代码。 让我们说我们正在编写一个排序函数。 我们一开始
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及其用法 。
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 << ",";
输出:
1, 3, 0, 2, 4,
<
的第一个问题是,在C ++标准下, <
on pointers对于任何不指向同一“父”对象或数组的东西都是完全无稽之谈。
这是因为存在分段存储模型,如8086。 通过忽略段号在段内进行比较要快得多,并且对象不能跨越段; 所以<
只能比较段内的偏移量并忽略段号。
在同样奇怪的硬件上还会出现这样的其他情况; 想象一下硬件,其中const(ROM)和非const(RAM)数据存在于一个单独的存储空间中。
std::less<Pointer>
同时保证了严格的弱排序,尽管内存架构中存在任何怪癖。 它将为每次比较付出代价。
我们需要std::less
的第二个原因是能够在easiliy周围传递“小于”的概念。 看看std::sort
的3参数重载:
void sort( Iterator, Iterator, Comparator )
在这里我们可以传递我们想要在第3个参数中排序的方式。 如果我们传递std::greater<Foo>{}
我们得到一种,如果我们传递std::less<Foo>{}
我们会得到相反的结果。
默认情况下,2参数版本的排序类似于std::less
,但是一旦你有更大,更大的相等,更少相等,添加更少只是有意义。
一旦你定义了更少,用它来描述默认std sort和std map之类的行为比重复所有关于它如何使用的措辞更容易<
除非它是在指针上然后它产生严格的弱排序同意<
where <
在标准中有完全指定的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.