为什么没有std :: sort通过引用接受比较?

时间:2014-07-29 10:29:24

标签: c++ c++11 stl

standard on std::reference_wrapper解释std::sort现在接受std::reference_wrapper,允许其通过引用传递比较器。

是否有理由std::sort首先没有通过引用接受比较器?

2 个答案:

答案 0 :(得分:17)

简而言之,没有必要参考;它相当于一个"设计"决定。

我认为推理主要围绕C ++和标准库中存在的一些基础知识很长一段时间;

  • 价值语义
  • 尽可能减少对实施的限制

价值语义几乎可以在任何地方看到。几乎所有算法,容器等都期望其中包含的数据遵循正常的值规则,即表现得好像它们是内置类型。这也是C ++类型系统背后的原因之一,使用户类型的行为就像内置类型一样。

算法的实现可以根据需要自由复制函数参数。当允许实现复制仿函数时,将签名限制为引用并不是很有用;所以只需从一开始就允许复制。这意味着函数对象不应该包含任何状态,它可能不会被保留;反过来,这有效地使仿函数变得非常轻,并且无论如何都没有理由进行参考。

  

25.1 / 10 算法库(C ++ draft n3797)

     

[注意:除非另有说明,否则允许将函数对象作为参数的算法自由复制这些函数对象。对象标识很重要的程序员应考虑使用指向非复制实现对象(如reference_wrapper(20.9.3))或某种等效解决方案的包装类。 - 后注]

关于API设计的一般说明。规范和标准的API设计,特别是模板的API设计,在最好的时候是一项非常重要的任务。委员会今天是否会以不同的方式设计r值,参考折叠,完美转发和移动语义?我不知道。在我看来,通过值获取函数对象可以平衡与内部副本和移动相关的问题,可能的优化以及与临时对象的绑定(pr值/ x值)。 A"通用参考"这可能会更好,但我觉得遗留的论点会超过支持改变的论据。

答案 1 :(得分:7)

在C ++ 03中,通过引用接受比较器将阻止绑定到非const rvalue,例如函数指针表达式:

bool comp(T const&, T const&);
sort(first, last, &comp);

或临时的仿函数:

struct Comparator { bool operator()(T const&, T const&) { ... } };
sort(first, last, Comparator());

在C ++ 11中,通过通用引用获取比较器可以避免这个问题,但这是一个不必要的更改,因为我们有reference_wrapper