[英]Template class specialization vs function overloading
The title is not the best so let me explain: I'm experimenting with a custom mini-stl (for learning purposes) and currently implementing the std::distance
function. 标题不是最好的,所以让我解释一下:我正在试验一个自定义的mini-stl(出于学习目的),当前正在实现
std::distance
函数。 The function must behave differently for random access iterators and simple input iterators. 对于随机访问迭代器和简单输入迭代器,该函数的行为必须有所不同。
Function overloading 函数重载
Both std (in Microsoft's implementation) and EASTL use operator overloading to select the appropriate function, something like this: std(在Microsoft的实现中)和EASTL都使用运算符重载来选择适当的函数,如下所示:
namespace internal
{
template <typename Iter>
inline typename IteratorTraits<Iter>::DifferenceType DistanceImpl(Iter first, Iter last, InputIteratorTag)
{
// ...
}
template <typename Iter>
inline typename IteratorTraits<Iter>::DifferenceType DistanceImpl(Iter first, Iter last, RandomAccessIteratorTag)
{
// ...
}
}
template <typename Iter>
inline typename IteratorTraits<Iter>::DifferenceType Distance(Iter first, Iter last)
{
// the last parameter of the function selects the proper DistanceImpl
return internal::DistanceImpl<Iter>(first, last, (typename IteratorTraits<Iter>::IteratorCategory)());
}
I guess the temporary object (the category tag parameter which is an empty struct) will be optimized away since it's not used. 我猜临时对象(类别标记参数是一个空结构)将被优化掉,因为它没有被使用。
Class specialization with static function 具有静态功能的类专门化
What's about the specialization of a helper class with a static function? 带有静态函数的辅助类的专业化如何?
namespace internal
{
template <typename Cat>
struct DistanceImpl;
template <>
struct DistanceImpl<InputIteratorTag>
{
template <typename Iter>
inline static typename IteratorTraits<Iter>::DifferenceType Calc(Iter first, Iter last)
{
// ...
}
};
template <>
struct DistanceImpl<RandomAccessIteratorTag>
{
template <typename Iter>
inline static typename IteratorTraits<Iter>::DifferenceType Calc(Iter first, Iter last)
{
// ...
}
};
}
template <typename Iter>
inline typename IteratorTraits<Iter>::DifferenceType Distance(Iter first, Iter last)
{
return internal::DistanceImpl<typename IteratorTraits<Iter>::IteratorCategory>::Calc<Iter>(first, last);
}
Questions 问题
Tag dispatch automatically handles inheritance hierarchies; 标记分派可自动处理继承层次结构; explicit specializations don't.
明确的专业则没有。 This is particularly important with iterators, because the standard iterator category tags form an inheritance hierarchy:
random_access_iterator_tag
derives from bidirectional_iterator_tag
which derives from forward_iterator_tag
which derives from input_iterator_tag
. 这是迭代器尤为重要,因为迭代器分类标签形成一个继承层次:
random_access_iterator_tag
派生自bidirectional_iterator_tag
从派生forward_iterator_tag
从派生input_iterator_tag
。
The first version works out of the box when given a forward or bidirectional iterator by selecting the input iterator overload. 通过选择输入迭代器重载为它提供前向或双向迭代器时,第一个版本即开即用。 The second doesn't and requires additional specializations or some other changes.
第二个不需要,并且需要其他专业化或其他一些更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.