2

假设我想要一些简单的东西,如下所示:

我有一个核心算法,它随机选择一种专门的算法(在编译时专门)并处理这个算法。这些专门的算法是通过函子实现的。

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

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

奇怪地重复出现的模板习语有什么联系吗?(维基链接
有没有使用Boost::Fusion的简单方法?(官方文档

编辑:所有算法都将用于核心算法。使用模式(随机数)是运行时决策(所以我不需要编译时随机数)。该算法只需要知道函子的容器和该容器的大小即可安全访问。

4

3 回答 3

3

如果你想让你的核心算法执行一个专门的算法,核心算法和专门的算法之间应该有某种契约。

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

class IAlgorithm
   {
   public:
      virtual double operator()(double d) = 0;
   };

typedef std::vector<IAlgorithm *> Algorithms;

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

或者,您也可以使用新的 C++0x std::function 构造,如下所示:

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

取一个算法是类似的,你应该可以这样调用一个算法:

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

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

编辑:这是一个使用 lambda 的示例。它可以按预期与 Visual Studio 2010 一起编译和工作(我自己刚刚测试过):

#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;
}
于 2010-11-09T10:28:37.563 回答
0

我不是专家,但我认为 boost::fusion 和/或boost::mpl确实是您正在寻找的工具。

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

于 2010-11-09T10:28:08.517 回答
0

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

也许是这样的:)

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

输出:15 2

于 2010-11-09T11:40:56.920 回答