Template methods 与NOT C ++模板一样。
所以,假设你想用不同的算法进行一些搜索 - 例如Linear和Binary。而且您还希望通过一些常见例程运行这些搜索,以便您可以自动记录给定搜索所花费的时间等等。
模板方法模式很好地填补了账单。唯一的问题是,就我已经设法挖掘而言,你无法通过C ++的静态方法实际实现这种行为,因为你还需要使方法成为虚拟(?)这当然有点无聊,因为我没有必要改变搜索对象的状态。我只想将所有搜索内容固定到自己的命名空间。
所以问题是: 是否会想要使用类似函数/方法指针的东西?或者只是使用命名空间来完成这项工作?
很难忍受C ++的这种(我敢说的)限制,因为像这样的东西对Java来说是轻而易举的。
修改
哦,是的,因为这是一项学校作业,使用外部库(STL除外)实际上并不是一种选择。对不起,麻烦。
答案 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
将是“我不需要改变对象的状态”,并且您可以使用virtual
和const
的方法。
答案 3 :(得分:0)
你总是可以像在Java中一样实现它 - 传入一个带有search()方法的抽象类ISearchable,并在LinearSearch和BinarySearch中覆盖它......
你也可以使用函数指针(这将是我的优先解决方案)或boost :: function,或者模板化你的函数并传入函子。