C ++ w /静态模板方法

时间:2009-07-21 19:18:42

标签: c++

Template methods 与NOT C ++模板一样

所以,假设你想用不同的算法进行一些搜索 - 例如Linear和Binary。而且您还希望通过一些常见例程运行这些搜索,以便您可以自动记录给定搜索所花费的时间等等。

模板方法模式很好地填补了账单。唯一的问题是,就我已经设法挖掘而言,你无法通过C ++的静态方法实际实现这种行为,因为你还需要使方法成为虚拟(?)这当然有点无聊,因为我没有必要改变搜索对象的状态。我只想将所有搜索内容固定到自己的命名空间。

所以问题是: 是否会想要使用类似函数/方法指针的东西?或者只是使用命名空间来完成这项工作?

很难忍受C ++的这种(我敢说的)限制,因为像这样的东西对Java来说是轻而易举的。

修改

哦,是的,因为这是一项学校作业,使用外部库(STL除外)实际上并不是一种选择。对不起,麻烦。

4 个答案:

答案 0 :(得分:5)

我不明白为什么你需要模板方法模式。

为什么不将这些算法定义为可以传递给基准函数的仿函数?

struct BinarySearch { // functor implementing a specific search algorithm
  template <typename iter_type>
  void operator()(iter_type first, iter_type last){ ....}
};

template <typename data_type, typename search_type>
void BenchmarkSearch(data_type& data, search_type search){ // general benchmarking/bookkeeping function
// init timer
search(data);
// compute elapsed time
}

然后像这样调用它:

int main(){
  std::vector<int> vec;
  vec.push_back(43);
  vec.push_back(2);
  vec.push_back(8);
  vec.push_back(13);

  BenchmarkSearch(vec, BinarySearch());
  BenchmarkSearch(vec, LinearSearch()); // assuming more search algorithms are defined
  BenchmarkSearch(vec, SomeOtherSearch();
}

当然,另一种方法,更接近你最初想要的方法,可能是使用CRTP(一种非常聪明的模式,用于在编译时模拟虚函数 - 它也适用于静态方法):

template <typename T>
struct SearchBase { // base class implementing general bookkeeping
  static void Search() {
    // do general bookkeeping, initialize timers, whatever you need
    T::Search(); // Call derived search function
    // Wrap up, do whatever bookkeeping is left
  }
}


struct LinearSearch : SearchBase<LinearSearch> // derived class implementing the specific search algorithms
{
  static void Search(){
    // Perform the actual search
  }
};

然后你可以调用静态函数:

SearchBase<LinearSearch>::Search();
SearchBase<BinarySearch>::Search();
SearchBase<SomeOtherSearch>::Search();

作为最后一点,值得一提的是,这两种方法都应该带来零开销。与涉及虚函数的任何事物不同,编译器完全知道在这里调用哪些函数,并且可以并且将内联它们,从而产生与您对每个案例进行手工编码一样高效的代码。

答案 1 :(得分:2)

这是一个简单的模板化版本

template <typename F, typename C>
clock_t timer(F f, C c)
{
    clock_t begin = clock();
    f(c);
    return clock() - begin;
}

void mySort(std::vector<int> vec)
{ std::sort(vec.begin(), vec.end()); }

int main()
{
    std::vector<int> vec;
    std::cout << timer(mySort, vec) << std::endl;
    return 0;
}

答案 2 :(得分:1)

static没有说“我不需要改变对象的状态”是说“我不需要对象”。如果需要虚拟分派,则需要一个对象来执行虚拟分派,因为虚拟分派是基于对象的运行时类型的多态。 const将是“我不需要改变对象的状态”,并且您可以使用virtualconst的方法。

答案 3 :(得分:0)

你总是可以像在Java中一样实现它 - 传入一个带有search()方法的抽象类ISearchable,并在LinearSearch和BinarySearch中覆盖它......

你也可以使用函数指针(这将是我的优先解决方案)或boost :: function,或者模板化你的函数并传入函子。