6

我只是想知道,既然您无论如何只能将随机访问迭代器传递给std::sort,为什么不首先为随机访问迭代器定义它来强制执行该限制呢?

#include <iterator>
#include <type_traits>

template <typename ForwardIterator>
typename std::enable_if<
    std::is_same<
        typename std::iterator_traits<ForwardIterator>::iterator_category,
        std::random_access_iterator_tag>::value,
    void>
::type sort(ForwardIterator begin, ForwardIterator end)
{
    // ...
}

我发现单行错误消息比实现中的类型错误导致的页面和页面更容易阅读。

你可以对其他算法做同样的事情。标准的 C++ 核心语言对于这项任务的表现力已经足够了,对吧?那么,没有这样做的任何特殊原因?

4

4 回答 4

6

核心语言一直具有足够的表达能力来处理此类检查,但是在准备第一个标准时(大约 1996/1997 年),您可以使用 SFINAE 玩的技巧(enable_if所基于的)尚不为人所知,并且支持高级模板向导在编译器中受到限制。

因此,该标准没有强制要求它的原因是因为尚未发明所需的技术。
编译器/库编写者事后没有添加它的原因可能只是简单的经济学:没有足够的人要求该功能,当人们确实开始要求更好的诊断时,希望就在概念提案上来处理它。不幸的是,事实证明这有点难以及时完成。

于 2011-01-22T17:29:41.180 回答
3

我的猜测是 SFINAE 是在标准库实现达到一定成熟度之后发明(或发现)的。在那之后,为了防止引入回归,对核心库的更改必须非常合理,我想单纯的装饰有点难以证明是合理的。

也就是说,例如 GCC 已经模板相关的错误消息进行了很多诊断,例如执行某种概念检查的宏。例如,GCC-libstdc++ 有以下内容:

// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
   _RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
于 2011-01-22T16:23:21.190 回答
0

实际上,当一个算法只有一个重载时,您几乎总能通过使用类似 Boost.ConceptCheck 或__glibcxx_function_requires. 当 SFINAE(enable_if使用它)给您留下一个空的重载集时,大多数编译器只会告诉您“没有匹配的函数”,这往往不是很有帮助。

于 2015-02-15T06:13:06.583 回答
-3

C++ 中模板的优点之一是它们可以有一种静态的“鸭子类型”。我不能说这种特殊情况,但是在许多模板中,只要您保持界面相同,所有层次结构的废话都无关紧要。这是一件好事。

于 2011-01-23T17:27:17.287 回答