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

这是一个功能的三个功能。有没有更简单的方法来实现这一点,例如使用boost::is_base_of或某事。在 if 条件或 boost::enable if 中类似,用于将函数输出转换为不派生自的类的一种常量Timed。不幸的是,具有虚拟功能的解决方案不是一种选择。

4

3 回答 3

5

你可以用两个简单的重载而不用模板机制来做同样的事情:

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

现在,向用户公开了一个函数,以及本地类中的实际实现。

顺便说一句,在 C++11 中,您可以使用std::is_base_of而不是 boost 的版本。与std::true_type和相同std::false_type

于 2012-02-07T16:43:03.673 回答
0

用于enable_if在可能的过载之间进行选择。由于以下示例中使用的条件是互补的,因此总会有一个可用的重载,因此没有歧义

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 回答