我正在编写partition
函数,它是Bidirectional
和Forward
迭代器的专业化。
我不确定如果订单影响结果,那就是这两个版本是不同的。
第一
template< class BIter, class UnaryPredicate>
BIter __partition( BIter first,
BIter last,
UnaryPredicate pred,
std::bidirectional_iterator_tag);
template<typename FIter, typename UnaryPredicate>
FIter __partition(FIter first,
FIter last,
UnaryPredicate pred,
std::forward_iterator_tag);
template<typename FIter, typename UnaryPredicate>
FIter newton::partition(FIter first,
FIter last,
UnaryPredicate pred)
{
return newton::__partition(first, last, pred, std::__iterator_category(first));
}
第二
template<typename FIter, typename UnaryPredicate> FIter
__partition(FIter first,
FIter last,
UnaryPredicate pred,
std::forward_iterator_tag);
template< class BIter, class UnaryPredicate>
BIter __partition(BIter first,
BIter last,
UnaryPredicate pred,
std::bidirectional_iterator_tag);
template<typename FIter, typename UnaryPredicate>
FIter newton::partition(FIter first,
FIter last,
UnaryPredicate pred)
{
return newton::__partition(first, last, pred, std::__iterator_category(first));
}
我看到gcc,llmv等使用第二个版本,但是...我读到编译器使用它的原型适合的第一个函数。
并不是Bidirectional Iter
适合Forward Iter
,然后使用该函数而不是专门的?
答案 0 :(得分:3)
不,订单无关紧要。
如果category参数正好是std::bidirectional_iterator_tag
,则一个函数比需要转换为基类的函数更好。
答案 1 :(得分:2)
哇哇!那不是真的。编译器执行overload resolution以找到函数调用的最佳候选者,无论它们之前的顺序如何。我读到编译器使用了它的原型适合的第一个函数。
当然,如果你在两者之间的中间有一个功能,你将无法拨打第二个(假设你没有第二个声明),但是这不是这种情况,因为只要你称之为两个重载就知道了。
并不是
Bidirectional Iter
适合Forward Iter
,然后使用该函数而不是专门的?
在这种情况下不行,因为代码使用的是一种称为标签分派的技术。 &#34;标签&#34;是完全独立的,通常只是一个空类struct some_tag {};
(虽然不是这种情况)。如果情况并非如此,那么仍然没有,因为仍然会发生重载解析,即使双向迭代器可以转换为正向迭代器,仍然存在不需要任何更好匹配的转换的重载。
答案 2 :(得分:1)
我读到编译器使用它的原型适合的第一个函数。
Nope:它形成了一组可能的候选函数 - 这些函数具有正确的名称,可以匹配您的调用站点上的参数。然后它决定(或试图决定)哪个是最佳匹配。
这称为overload resolution(和名称查找,以及该页面顶部链接的其他内容)。
...
的情况Bidirectional Iter
不符合Forward Iter
排序。
你要结合两件事:
也就是说,您可以逻辑说BidirectionalIterator 是-a ForwardIterator,和 std::bidirectional_iterator_tag
是-a {{ 1}},以及你的重载
std::forward_iterator_tag
对于双向迭代器,是但是,根据链接页面的隐式转换序列的排名部分,第二个重载是更好的匹配(它是精确的匹配,正如你所期望的那样是你能得到的最好的。)
因此,我们可以更准确地说,两个重载之间没有歧义。