Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板类专门化与函数重载_C++_C++11 - Fatal编程技术网

C++ 模板类专门化与函数重载

C++ 模板类专门化与函数重载,c++,c++11,C++,C++11,标题不是最好的,所以让我解释一下:我正在试验一个定制的迷你stl(用于学习目的),目前正在实现std::distance功能。对于随机访问迭代器和简单输入迭代器,函数的行为必须不同 函数重载 std(在Microsoft的实现中)和EASTL都使用运算符重载来选择适当的函数,如下所示: namespace internal { template <typename Iter> inline typename IteratorTraits<Iter>::Di

标题不是最好的,所以让我解释一下:我正在试验一个定制的迷你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)());
}
名称空间内部
{
模板
内联typename迭代器Raits::DifferenceType DistanceImpl(Iter first、Iter last、InputIteratorTag)
{
// ...
}
模板
内联typename迭代器Raits::DifferenceType DistanceImpl(Iter first、Iter last、RandomAccessIteratorTag)
{
// ...
}
}
模板
内联类型名迭代器属性::差异类型距离(Iter优先,Iter最后)
{
//函数的最后一个参数选择适当的距离impl
返回internal::DistanceImpl(first,last,(typename IteratorTraits::IteratorCategory)();
}
我猜临时对象(category tag参数是一个空结构)将被优化掉,因为它没有被使用

具有静态函数的类专门化

一个带有静态函数的helper类的特殊化是什么

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);
}
名称空间内部
{
模板
结构距离;
模板
结构距离impl
{
模板
内联静态类型名IteratorTraits::DifferenceType Calc(Iter优先,Iter最后)
{
// ...
}
};
模板
结构距离impl
{
模板
内联静态类型名IteratorTraits::DifferenceType Calc(Iter优先,Iter最后)
{
// ...
}
};
}
模板
内联类型名迭代器属性::差异类型距离(Iter优先,Iter最后)
{
返回内部::距离impl::计算(第一个,最后一个);
}
问题

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

标记分派自动处理继承层次结构;显式专门化不起作用。这对于迭代器尤其重要,因为标准迭代器类别标记形成一个继承层次:
随机访问迭代器标记
派生自
双向迭代器标记
,它派生自
前向迭代器标记
,后者派生自
输入迭代器标记


当通过选择输入迭代器重载指定正向迭代器或双向迭代器时,第一个版本是开箱即用的。第二种方法没有,需要额外的专门化或其他一些更改。

相反,使用专门化方法没有错。这就是我要用的。编译器很可能会优化无用的临时文件,因此最终会得到相同的结果。正如公认的答案所说,专用方法不适用于例如
双向迭代器标记
哦,是的,完全忘记了继承问题。对象本身(类别标签)将被优化掉,对吗?因此,没有表现惩罚。