我总是想知道为什么没有
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
答案 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)
之类的东西可以工作,而不必显式指定范围或迭代器。