1

一部の Timestamp プロパティ (クラスは から継承) をチェックするテンプレート関数を作成したいと考えてTimedいますが、タイムスタンプを持たない型に対しても機能する必要があります。私が見つけた最良の(そしてまだかなり醜い)解決策は次のとおりです。

class Timed {
  protected:
    int mTime;        
  public:
    explicit Timed(int time=0): mTime(time){}
    int getT() const {return mTime;}

};

template<typename T>
bool checkStale(T const* ptr) const {
  return checkStaleImp(ptr, boost::is_base_of<Timed, T>() );
}

template<typename T>
template<bool b>
bool checkStaleImp(T const* ptr, boost::integral_constant<bool, b> const &){
  return true;
}

template<typename T>
bool checkStaleImp(T const* ptr, boost::true_type const&){
  const int oldest = 42;
  return (42 <= ptr->getT());  
}

これは、1 つの機能に対して 3 つの機能です。これを達成するためのより簡単な方法はありますboost::is_base_ofか? if 条件または boost::enable if で同様に、関数出力を から派生していないクラスの一種の定数に変換しますTimed。残念ながら、仮想機能を使用したソリューションはオプションではありません。

4

3 に答える 3

5

2 つの単純なオーバーロードを使用して、テンプレート機構を使用せずに同じことを行うことができます。

bool checkStale(void const* ptr){
  return true;
}

bool checkStale(Timed const* ptr){
  const int oldest = 42;
  return (oldest <= ptr->getT());  
}

でタグをディスパッチする必要はありませんis_base_of

于 2012-02-07T16:49:28.473 に答える
3

あなたが言ったように、それはかなり醜い解決策だとは思いません。ただし、次のようにローカル クラスの静的メンバーとしてヘルパー関数を実装すると、ヘルパー関数のスコープを縮小できます。

template<typename T>
bool checkStale(T const* ptr) const 
{
  struct local
  {
      static bool checkStaleImp(T const* ptr, boost::false_type const &)
      {
         return true;
      }
      static bool checkStaleImp(T const* ptr, boost::true_type const&)
      {
        const int oldest = 42;
        return (42 <= ptr->getT());  
      }
  };
  return local::checkStaleImp(ptr, boost::is_base_of<Timed, T>());
}

これで、ユーザー用に公開された 1 つの関数と、ローカル クラス内の実際の実装があります。

ちなみにC++11ではstd::is_base_ofboostの代わりに使えます。std::true_typeとと同じstd::false_typeです。

于 2012-02-07T16:43:03.673 に答える
0

enable_if可能な過負荷から選択するために使用します。次の例で使用されている条件は補完的であるため、利用可能なオーバーロードは常に 1 つだけであり、あいまいさはありません。

template<typename T>
typename std::enable_if<std::is_base_of<Timed,T>::value,bool>::type
checkStale(T const *ptr) const {
    const int oldest = 42;
    return oldest <= ptr->getT();
}

template<typename T>
typename std::enable_if<!std::is_base_of<Timed,T>::value,bool>::type
checkStale(T const *ptr) const {
    return true;
}
于 2012-02-07T16:47:47.557 に答える