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

控制算法的函子编译时容器?

  •  2
  • sascha  · 技术社区  · 15 年前

    我有一个核心算法,它随机选择一个专用算法(在编译时专用)并处理该算法。这些特殊的算法是通过 仿函数

    现在的问题是 :如何实现在编译时生成的容器,核心算法可以首先检查该容器的大小(“我得到4个算法->需要随机选择算法0-3”),然后可以在此容器中执行函子(“随机选择2->处理容器中的第三个函子”)。

    如何实现它尽可能简单?我想这是可能的。

    有什么联系吗 奇怪的重复模板习惯用法 ? ( wiki link )
    有没有简单的方法来使用 Boost::融合 ? ( official doc )

    编辑:

    3 回复  |  直到 15 年前
        1
  •  3
  •   Patrick    15 年前

    如果希望核心算法执行专用算法,则核心算法和专用算法之间应该存在某种契约。

    如果将此约定定义为接口,则容器只是包含指向这些接口的指针的容器,例如:

    class IAlgorithm
       {
       public:
          virtual double operator()(double d) = 0;
       };
    
    typedef std::vector<IAlgorithm *> Algorithms;
    

    调用随机算法就是简单地取向量的大小,取一个介于0和列表大小(0..size-1)之间的随机值,取该位置的条目并调用接口。

    #include <functional>
    typedef std::function<double(double)> Algorithm;
    typedef std::vector<Algorithm> Algorithms;
    

    采用类似的算法,您应该能够调用这样的算法:

    Algorithms myAlgorithms;
    ...
    double myresult = myAlgorithms[2](mydouble);
    

    这种方法的优点是您还可以使用lambda。

    编辑:

    #include <iostream>
    #include <vector>
    #include <functional> 
    typedef std::function<double(double)> Algorithm; 
    typedef std::vector<Algorithm> Algorithms; 
    
    int main()
    {
    Algorithms algorithms;
    algorithms.push_back([](double d)->double{return d+d;});
    algorithms.push_back([](double d)->double{return d*d;});
    
    std::cout << algorithms[0](5) << std::endl;
    std::cout << algorithms[1](5) << std::endl;
    }
    
        2
  •  0
  •   Klaim    15 年前

    我不是专家,但我认为确实是boost::fusion和/或 boost::mpl 是你要找的工具。

    您的类将以mpl容器作为参数,作为算法函子类型的列表,然后在编译时使用它。

        3
  •  0
  •   visitor    15 年前

    我认为一个有趣的子问题是如何在编译时生成随机数。

    可能是这样的:)

    //compiletime_rand.h
    
    #ifndef COMPILETIME_RAND_GENERATOR_H
    #define COMPILETIME_RAND_GENERATOR_H
    
    template <unsigned N, unsigned Seed, unsigned Modulo>
    struct rand_c_impl
    {
        static const unsigned value_impl = (1664525 * rand_c_impl<N - 1, Seed, Modulo>::value + 1013904223) % (1ull << 32);
        static const unsigned value = value_impl % Modulo;
    };
    
    template <unsigned Seed, unsigned Modulo>
    struct rand_c_impl<0, Seed, Modulo>
    {
        static const unsigned value_impl = Seed;
        static const unsigned value = value_impl;
    };
    
    #endif
    

    //next_c_rand.h
    
    #include BOOST_PP_UPDATE_COUNTER()
    
    rand_c_impl<BOOST_PP_COUNTER, 0, MAX_C_RAND>::value
    

    //main.cpp
    
    #include <boost/preprocessor/slot/counter.hpp>
    #include "compiletime_rand.h"
    
    #include <iostream>
    
    #define MAX_C_RAND 16
    
    template <unsigned N>
    void output_compiletime_value()
    {
        std::cout << N << '\n';
    }
    
    int main()
    {
        output_compiletime_value< 
    #include "next_c_rand.h"
        >();
        output_compiletime_value< 
    #include "next_c_rand.h"
        >();  
    }