我只是想知道,因为你只能将随机访问迭代器传递给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 ++核心语言一直都足以表达这项任务,对吧?那么,为什么没有这样做的任何特殊原因?
答案 0 :(得分:6)
核心语言一直表达足以表达这种检查,但是当第一个标准准备好时(1996/1997左右),你可以用SFINAE(enable_if所基于的)的技巧目前还不知道,编译器对高级模板魔法的支持有限。
因此,标准没有强制要求的原因是因为尚未发明所需的技术 编译器/库编写者之后没有添加它的原因可能只是简单的经济学:没有足够的人要求这个功能,当人们开始要求更好的诊断时,希望是concepts提出的建议关心它。不幸的是,事实证明这有点太难以及时完成。
答案 1 :(得分:3)
我的猜测是SFINAE是在标准库实现达到一定成熟度后发明(或发现)的。在此之后,核心库的更改必须是非常合理的,以防止引入回归,我想仅仅化妆品有点难以证明。
也就是说,例如GCC已经 对模板相关的错误消息进行了大量诊断,例如:执行一种概念检查的宏。例如,GCC-libstdc ++具有以下内容:
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
__glibcxx_requires_valid_range(__first, __last);
答案 2 :(得分:0)
实际上,当一个算法只有一个重载时,你几乎总能通过使用像Boost.ConceptCheck或__glibcxx_function_requires
这样的内部引起编译错误来获得更好的诊断。当SFINAE(这是enable_if
使用的)给你留下一个空的重载集时,大多数编译器只是告诉你“没有匹配的函数”,这往往不是很有帮助。
答案 3 :(得分:-3)
C ++模板的一个好处是它们可以有一种静态的“鸭子打字”。我无法代表这种特殊情况,但在许多模板中,只要保持界面相同,所有层次结构无意义都无关紧要。这是一件好事。