模板类专业化与功能重载

时间:2017-01-02 13:41:28

标签: c++ c++11

标题不是最好的,所以让我解释一下:我正在尝试使用自定义mini-stl(用于学习目的)并且正在实现std::distance功能。对于随机访问迭代器和简单的输入迭代器,函数必须有不同的行为。

功能重载

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)());
}

我想临时对象(类别标签参数是一个空结构)将被优化掉,因为它没有被使用。

具有静态功能的班级专业化

具有静态函数的辅助类的特化是什么?

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);
}

问题

  • 两种解决方案之间的差异? (包括性能和可靠性)
  • 优点/缺点?

1 个答案:

答案 0 :(得分:3)

标签分派自动处理继承层次结构;明确的专业化不是。这对于迭代器尤为重要,因为标准迭代器类别标记构成了一个继承层次结构:random_access_iterator_tag派生自bidirectional_iterator_tag,派生自forward_iterator_tag,派生自input_iterator_tag

通过选择输入迭代器重载,第一个版本在给定正向或双向迭代器时开箱即用。第二个并不需要额外的专业化或其他一些改变。