[英]Template class specialization vs function overloading
標題不是最好的,所以讓我解釋一下:我正在試驗一個自定義的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);
}
問題
標記分派可自動處理繼承層次結構; 明確的專業則沒有。 這是迭代器尤為重要,因為迭代器分類標簽形成一個繼承層次: random_access_iterator_tag
派生自bidirectional_iterator_tag
從派生forward_iterator_tag
從派生input_iterator_tag
。
通過選擇輸入迭代器重載為它提供前向或雙向迭代器時,第一個版本即開即用。 第二個不需要,並且需要其他專業化或其他一些更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.