为什么在C ++中没有排序(v)?

时间:2012-06-24 02:15:11

标签: c++ stl

我总是想知道为什么没有

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自己解释了这些概念,以排序为例:) 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

6 个答案:

答案 0 :(得分:10)

这不是std::sort(v) - &gt; std::sort(v.begin(), v.end())扩展需要概念,但备用排序函数需要额外的参数进行比较 - std::sort(v.begin(), v.end(), compare)

如果您有一个电话std::sort(v, compare),实施需要概念,以便将其与std::sort(start, end)区分为非容器。

<algorithm>标题中包含这类问题的模板。

答案 1 :(得分:5)

来自Learning Standard C++ as a New Language (PDF) Stroustrup,C / C ++ Users Journal。第43-54页。 1999年5月:

  

在这种情况下,普通排序(v)会更简单,但有时我们想要对a的一部分进行排序   容器因此更通用地指定我们想要排序的开始和结束。

这对我有意义。正如你所展示的那样,创建一个包装器是微不足道的,没有包装器使用它并不是非常麻烦。拥有容器的第二个sort()似乎不值得。

答案 2 :(得分:3)

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

答案 3 :(得分:1)

这没有什么需要概念。范围并不比迭代器复杂得多。

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

概念不是必需的 - 但是(因为它们是在C ++ 11标准化期间提出的),它们可以很容易地实现它。

就目前而言,可以通过为std::sort提供一些额外的重载(或可能是明确的特化)来实现这一点。当然,问题是std::sort并不是唯一的算法,所以你无疑也希望对许多其他算法也做同样的事情(几乎所有算法都是如此)。

概念(具体来说,概念图,如果内存服务)会提供一种相对干净的方式来以相对集中的方式提供(相当于)所有这些重载,所以你将所有这些适配器放在一个地方而不是N地方(每个算法一个)。更好的是,只要它们符合常规惯例,它也适用于其他算法。

相当多的人认为范围是应该处理的方式 - 算法应该在范围上运行,并且任何容器都应该定义范围(但是应该有其他方法来定义范围)。虽然这可能是一个很好的概念,但似乎(至少在我看来)对于应该构成范围的具体细节,应该如何定义等等存在相当大的分歧。

如果你真的想探索这个,Boost已经有一个range library,其中包括大多数标准算法的基于范围的版本(以及其他许多算法)。至少如果内存服务,这包括一些从容器创建范围的适配器,所以sort(c)之类的东西可以工作,而不必显式指定范围或迭代器。