假设我想要一些简单的东西:
我有一个核心算法,它随机选择一个专门的算法(专门编译时)并处理这个算法。这些专业算法通过仿函数实现。
现在的问题是:如何实现一个在编译时构建的容器,其中核心算法可以首先检查这个容器的大小(“我有4个算法 - &gt ;需要随机选择算法0-3“)然后可以在此容器中执行仿函数(”随机选择2 - >处理容器中的第三个仿函数“)。
如何尽可能简单地实现它?我想这是可能的。
是否与好奇的重复出现的模板成语有关联? (wiki link)
使用 Boost :: Fusion 有一种简单的方法吗? (official doc)
编辑:所有算法都将用于核心算法。使用模式(随机数)是运行时决策(所以我不需要编译时间)。该算法只需要知道仿函数的容器和这个容器的大小,以便安全访问。
答案 0 :(得分:3)
如果您希望核心算法执行专门的算法,核心算法和专用算法之间应该存在某种契约。
如果将此合约定义为接口,则容器只是一个包含指向这些接口的指针的容器,例如:
class IAlgorithm
{
public:
virtual double operator()(double d) = 0;
};
typedef std::vector<IAlgorithm *> Algorithms;
调用随机算法然后简单地取矢量的大小,取零和列表大小之间的随机值(0..size-1),取该位置的条目并调用接口。 / p>
或者,您也可以使用新的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;
}
答案 1 :(得分:0)
我不是专家,但我认为确实是boost :: fusion和/或boost::mpl是你正在寻找的工具。
你的类将把一个mpl容器作为参数,作为算法函数类型的列表,然后在编译时使用它。
答案 2 :(得分: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