我遇到Boost.MPL的问题,我不知道如何处理它。目前是我的代码 看起来像这样:
struct Definition {
typedef boost::mpl::int_<5> A;
typedef boost::mpl::int_<3> B;
typedef boost::mpl::int_<6> C;
typedef boost::mpl::int_<1> D;
// (...)
typedef boost::mpl::vector<
A
,B
,C
,D
// (...)
> Seq;
};
此处,N
中的数字mpl::int_< N >
表示任意小数
数。然后一些其他代码计算这些数字的总和
由“key”定义的类型,例如对于Definition::D
,总和是5 + 3 + 6
(A + B + C)。这需要在编译时完成。这就是我使用的原因
mpl::vector
和一些适当的元编程。
我不喜欢当前的方法,因为它以某种方式违反了DRY规则。
我想知道是否有可能提供这样的结构
定义而不需要在mpl::vector
中重复类型名称
Seq
类型。换句话说,我可能需要一堆宏
允许我写这样的代码:
struct Definition {
FIELD(A, 5);
FIELD(B, 3);
FIELD(C, 6);
FIELD(D, 1);
// (...)
GEN_SEQ() // only if really needed
};
然后Definition::A
仍会引用boost::mpl::int_<5>
或
至少允许我以某种方式访问boost::mpl::int_<5>
,并且
Definition::Seq
会给我合适的MPL序列。
这只是我的想象力。代码可能看起来不一样,我是 只是寻找选择。
答案 0 :(得分:1)
我认为,为了以编程方式执行所有操作,您需要将字段的名称设置为可访问的内容 - 如果您只是将它们命名为A
,B
,... isn&#39真的。您可以尝试使您的序列包含两者:
using namespace boost::mpl; // so I don't have to keep typing it
typedef map<
pair<char_<'A'>, int_<5>>,
pair<char_<'B'>, int_<3>>,
pair<char_<'C'>, int_<6>>,
...
> Seq;
这样,总结到'D'
,你会得到:
template <char C>
struct sum_up_to {
typedef typename boost::mpl::copy_if<Seq,
less_than<C>,
boost::mpl::back_inserter< boost::mpl::vector<> >
>::type NewSeq;
typedef typename boost::mpl::accumulate<NewSeq,
boost::mpl::int_<0>,
addNext>::type type;
static const int value = type::value;
};
我将less_than<C>
和addNext
的实施方式留给您。但是这样你就可以sum_up_to<'D'>::value == 14
。
答案 1 :(得分:1)
你见过metamonad吗?它有可变的抽象,就像你想要的那样:
#include <mpllibs/metamonad/eval_multi_let_c.hpp>
#include <mpllibs/metamonad/pair.hpp>
#include <mpllibs/metamonad/syntax.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/assert.hpp>
#include <mpllibs/metamonad/metafunction.hpp>
#include <mpllibs/metamonad/lazy_metafunction.hpp>
#include <mpllibs/metamonad/returns.hpp>
#include <mpllibs/metamonad/name.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/times.hpp>
#include <boost/mpl/divides.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/minus.hpp>
#include <boost/mpl/equal_to.hpp>
int main()
{
using namespace mpllibs::metamonad::name;
using boost::mpl::equal_to;
using boost::mpl::plus;
using boost::mpl::map;
using boost::mpl::int_;
using mpllibs::metamonad::eval_multi_let_c;
using mpllibs::metamonad::syntax;
using mpllibs::metamonad::pair;
// test_evaluation_of_expression
static_assert(
equal_to<
int_<14>,
eval_multi_let_c<
map<
pair<a, syntax<int_<5>> >,
pair<b, syntax<int_<3>> >,
pair<c, syntax<int_<6>> >
>,
plus<a, b, c> >::type
>::value, "Yay, maths still work"
);
}