代码之家  ›  专栏  ›  技术社区  ›  JHollanti

C++ W/静态模板方法

c++
  •  0
  • JHollanti  · 技术社区  · 15 年前

    Template methods 在非C++模板中 .

    所以,假设您想用不同的算法进行一些搜索,例如线性和二进制。您还希望通过一些常见的例程运行这些搜索,这样您就可以自动记录给定搜索所花费的时间,等等。

    模板方法模式完美地填充了账单。唯一的问题是,就我所能找到的, 你不能用C++的静态方法来实现这个行为,因为你也需要让方法虚拟化(?) 当然,这有点令人不安,因为我不需要更改搜索对象的状态。我只想把所有的搜索内容固定到它自己的名称空间。

    所以问题是: 是否要使用类似于函数/方法指针的内容?或者只是使用名称空间来完成任务?

    用C++这样的(我敢说)限制是非常困难的,因为这样的事情对Java来说是微不足道的。

    编辑:

    哦,是的,既然这是学校的任务,使用外部图书馆(STL除外)并不是一个真正的选择。很抱歉有麻烦。

    4 回复  |  直到 12 年前
        1
  •  5
  •   Stack Overflow is garbage    15 年前

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

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

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

    最后一点需要注意的是,这两种方法的开销都应该为零。与涉及虚拟函数的任何内容不同,编译器完全知道在这里调用哪些函数,并且可以并且将它们内联,从而产生与手工编写每个案例一样高效的代码。

        2
  •  2
  •   Matt Price    15 年前

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

    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;
    }
    
        3
  •  1
  •   CB Bailey    15 年前

    static 不说“我不需要改变一个对象的状态”,就是说“我不需要一个对象”。如果您需要虚拟分派,那么您需要一个对象来执行虚拟分派,因为虚拟分派是基于对象运行时类型的多态性。 const 将是“我不需要更改对象的状态”,您可以使用 virtual 康斯特 .

        4
  •  0
  •   Greg Rogers    15 年前

    在一个抽象的类中,你可以用一个Selk()方法来实现它,并且在线性搜索和二进制搜索中重写它。

    您还可以使用函数指针(这将是我的首选解决方案)或boost::函数,或者模板化您的函数并传入一个函数。