c++ - 模板类特化与函数重载

标签 c++ c++11

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

函数重载

std(在微软的实现中)和 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);
}

问题

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

最佳答案

标签分发自动处理继承层次结构;明确的特化没有。这对于迭代器尤其重要,因为标准迭代器类别标签形成了继承层次结构:random_access_iterator_tag 派生自 bidirectional_iterator_tag 派生自input_iterator_tag

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

关于c++ - 模板类特化与函数重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41427954/

相关文章:

c++ - C++ 中的隐式变量初始化

c++ - 从逗号分隔的文本文件中创建有意义数据 vector 的最佳方法是什么

C++11 可变大小 POD 结构

c++ - 段错误 C++ 模板

c++ - 对 `forkpty' 的 undefined reference

c++ - 成员函数 .begin() 和 std::begin()

c++ - TR1 是 "missing"- 我的项目配置中缺少哪个 header 或库?

c++ - 为什么 std::deque 子数组大小是固定的?

c++ - 对std::vector的emplace_back感到困惑

c++ - 将 std::cout 重定向到 QTextEdit