2017-01-02 13 views
1

タイトルは最高ではありませんので、私に説明しましょう。私はカスタムミニストール(学習目的)を試していて、現在std::distance機能を実装しています。この関数は、ランダムアクセスイテレータとシンプル入力イテレータで異なる動作をする必要があります。テンプレートクラスの特殊化と関数のオーバーロード

機能、このような何か適切な機能を選択するために、オーバーロードを

両方(Microsoftの実装で)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)()); 
} 

を(カテゴリタグ空の構造体であるパラメータ)は使用されていないので最適化されます。静的機能付き

クラスの専門

は、静的な機能を備えたヘルパークラスの専門については何ですか? 2つの溶液との間

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

質問

  • 差(S)? (パフォーマンスと信頼性を含む)
  • 利点/欠点?
+1

特殊なアプローチを使用しても問題はありません。それが私が使うものです。コンパイラは、一時的に不具合を最適化する可能性が高いので、結果は同じになります。 –

+0

受け入れられた答えは、特殊なアプローチは、例えば、 'bidirectional_iterator_tag' – csisy

答えて

3

タグディスパッチは自動的に継承階層を処理します。明示的な専門化はしません。これはイテレータで特に重要です。標準イテレータカテゴリタグは継承階層を形成するため、はinput_iterator_tagに由来するforward_iterator_tagに由来するbidirectional_iterator_tagに由来します。

入力イテレータのオーバーロードを選択して、順方向または双方向のイテレータが指定されている場合は、最初のバージョンがそのまま使用できます。 2つめは追加の専門化やその他の変更を必要とせず、必要とします。

+0

ああ、それは本当に、相続問題を完全に忘れてしまった。オブジェクト自体(カテゴリタグ)は最適化されています。したがって、パフォーマンス上のペナルティはありません。 – csisy

関連する問題