为什么C++中没有sort(v)

why no sort(v) in C++?

本文关键字:sort C++ 为什么      更新时间:2023-10-16

我一直想知道为什么没有

sort(v);// same as std::sort(v.begin(),v.end())

如果我没记错的话,很久以前我看到过一个 boostcon 剪辑,演讲者说这需要概念,但我不明白为什么。顺便说一句,我试过这个(在 VS 11 中),从我所看到的来看,它的效果很好。

template <typename Container>
void sortfx(Container& c)
{
    std::sort(c.begin(),c.end());
}
int main()
{
    std::vector<double> v;
    //std::list<double> v; this causes compile errors
    v.push_back(1701);
    v.push_back(1729);
    v.push_back(74656);
    v.push_back(2063);
    sortfx(v);
    assert(std::is_sorted(begin(v),end(v)));
}

编辑:Bjarne自己解释了这些概念,并以sort为例:)https://www.informit.com/articles/article.aspx?p=2080042&WT.rss_f=Article&WT.rss_a=An%20Interview%20with%20Bjarne%20Stroustrup&WT.rss_ev=a

需要概念的不是std::sort(v) -> std::sort(v.begin(), v.end()) 扩展,而是采用附加参数进行比较的替代排序函数 - std::sort(v.begin(), v.end(), compare) .

如果你有一个调用std::sort(v, compare),实现将需要概念来区分它与非容器的std::sort(start, end)

<algorithm>标题中充满了存在此类问题的模板。

摘自学习标准C++作为新语言(PDF)Stroustrup,C/C++ Users Journal。 第43-54页。1999年5月:

在这种情况下,普通sort(v)会更简单,但有时我们想对 容器,因此更通用的是指定我们要排序的内容的开头和结尾。

这对我来说是有道理的。正如您所演示的,创建包装器是微不足道的,没有包装器使用并不是很麻烦。拥有第二个占用容器的sort()似乎不值得。

<algorithm>函数不能直接在容器上运行。它们只与迭代器交互,而不了解容器的任何上下文。如果您出于自己的目的使用短的全范围排序符号,我认为没有害处,但您必须假设对象具有开始/结束接口,这也恰好是双向迭代器。

这没有什么需要概念的。范围实际上并不比迭代器复杂。

如果您只想对容器的子集进行排序怎么办?

我最近几乎发布了一个类似的问题,关于为什么for_each不是Container的成员函数而不是独立的。 即 v.for_each([&sum] (int i) { sum += i; });

概念不是必需的 - 但是(正如它们在C++11标准化期间提出的那样)它们会使实现这一点变得相当容易。

就目前而言,您可以通过std::sort提供一些额外的重载(或可能的显式专业化)来做到这一点。当然,问题在于std::sort不是唯一的算法,所以你无疑也想对许多其他算法做同样的事情(几乎所有算法,最有可能)。

概念(

特别是概念图,如果没记错的话)将提供一种相当干净的方式来以相对集中的方式提供(等效的)所有这些重载,因此您将所有这些适配器放在一个地方而不是 N 个地方(每个算法一个)。更好的是,只要它们符合正常的约定,它也适用于其他算法。

目前有相当多的人认为范围是应该处理的方式——算法应该对范围进行操作,任何容器都应该定义一个范围(但也应该有其他方法来定义范围)。虽然这作为一个总体想法可能是好的,但似乎(至少对我来说)对于应该构成范围、如何定义它们的确切细节存在相当大的分歧。

如果你真的想探索这一点,Boost已经有一个范围库,其中包括大多数标准算法(以及其他一些算法)的基于范围的版本。至少如果没记错的话,这包括一些适配器来从容器创建范围,因此像sort(c)这样的东西就可以工作,而无需显式指定范围或迭代器。