c – boost.proto在构建表达式树之前检测无效终端

c – boost.proto在构建表达式树之前检测无效终端,第1张

概述我正在玩Boost.Proto,主要是为了好玩,看看将来我是否可以在我自己的项目中使用它.那说, 可能是这个库的大多数初学者,我玩过“懒惰矢量”示例的修改版本,但使用变换而不是上下文来执行评估.向量定义如下(好吧,我知道,’vector’对于在全局命名空间范围内定义的东西不是一个好名字……) template <std::size_t D, class T>class vector { 我正在玩Boost.Proto,主要是为了好玩,看看将来我是否可以在我自己的项目中使用它.那说,
可能是这个库的大多数初学者,我玩过“懒惰矢量”示例的修改版本,但使用变换而不是上下文来执行评估.向量定义如下(好吧,我知道,’vector’对于在全局命名空间范围内定义的东西不是一个好名字……)

template <std::size_t D,class T>class vector {     T data_[D];    enum { dimension = D };    // Constructors,destructors...};// @R_502_3725@ wrappertemplate <class> class vector_expr;

它是关于维度和数据类型的模板,boost :: array的种类(我没有使用它,因为我想重载operator =来接受表达式树,就像通常在这类事情中所做的那样).我使用proto手册中的代码定义了标量

// scalar = everything convertible to doublestruct scalar_terminal :    proto::terminal<proto::convertible_to <double> >{};// vector = everything for which the is_vector returns true_template <class T> struct is_vector : mpl::false_ {};template <std::size_t D,class T> struct is_vector <vector <D,T> > : mpl::true_ {};struct vector_terminal :    proto::and_ <       proto::terminal<_>,proto::if_<is_vector<proto::_value>()>  >{};// domain   struct vector_domain    : proto::domain <proto::generator <vector_expr> >{};// @R_502_3725@ wrappertemplate <class Expr>struct vector_expr : proto::extends <Expr,vector_expr <Expr>,vector_domain>{    typedef proto::extends <Expr,vector_domain> base_type;    // Construct from @R_502_3725@ (enough to compile)    vector_expr (Expr const &e) : base_type (e) {}};// Bring in operatorsBOOST_PROTO_define_OPERATORS(is_vector,vector_domain)

现在,我想要做的第一件事是:检查表达式中的所有向量终端是否都相同
维D.我最终得到了以下工作代码

// a Meta-function that returns the vector dimensiontemplate <class T>struct vector_dim{    typedef mpl::int_ <T::dimension> type;};// a Meta-function that combines dimensions from subtrees. int<-1> means// that sub-trees store vectors of differing static dimension. No good.template <class D1,class D2>struct dim_combine{   typedef mpl::int_ < -1 > type;};// ok,dimensions are the same,propagate up the valuetemplate <class D>struct dim_combine <D,D>{   typedef D type;};// 0 is used to mark scalars. It is ok to mix vectors and scalars// but propagate up the vector dimension only. This is for vector// on the left and scalar on the right.template <class D>struct dim_combine <D,mpl::int_ <0> >{   typedef D type;};// this is for scalar on the left,vector to the right of some // binary operator.template <class D>struct dim_combine <mpl::int_ <0>,D>{   typedef D type;};// need this too to avoID ambiguity between the two specializations// above when D is int_ <0>. Even if this combination should never// happentemplate <>struct dim_combine <mpl::int_ <0>,mpl::int_<0> >{   typedef mpl::int_<0> type;};// A transform that check that all arrays have the same dimensionstruct vec_dim_check    : proto::or_ <        proto::when <            vector_terminal,vector_dim<proto::_value>()        >,proto::when <            scalar_terminal,boost::mpl::int_<0>()        >,proto::when <            proto::nary_expr<_,proto::vararg<_> >,proto::fold<_,boost::mpl::int_<0>(),dim_combine<vec_dim_check,proto::_state>()>        >    >{};template <class E>voID check_dim (E const&){    typedef typename boost::result_of<vec_dim_check(E)>::type type;    BOOST_ASSERT(type::value == 3);}int main (int,char**){    vector <3,double> a,b,c;    check_dim (2*a+b/c);    return 0;}

问题是:由于数组的维度已经在表达式中编码,因此它应该
可以在编译时检测到无效组合.应该甚至可以避免
首先创建树.这是如何实现的?

在此先感谢,最好的问候

解决方法 非常好.现在你需要定义一个只接受有效矢量表达式的语法,如下所示:

struct vector_grammar_untyped  : proto::or_<        scalar_terminal,vector_terminal,proto::nary_expr<proto::_,proto::vararg<vector_grammar_untyped> >    >{};struct vector_grammar  : proto::and_<        vector_grammar_untyped,proto::if_<mpl::not_equal_to< mpl::int_<-1>,vec_dim_check >()>    >{};

然后,您更改vector_domain的定义,如下所示:

struct vector_domain    : proto::domain <proto::generator <vector_expr>,vector_grammar >{};

这应该使您无法创建不通过自定义类型检查的表达式. proto :: domain的第二个模板参数是该域中所有表达式必须符合的语法.

免责声明:上述代码未经测试,但它应该让您朝着正确的方向前进.

总结

以上是内存溢出为你收集整理的c – boost.proto在构建表达式树之前检测无效终端全部内容,希望文章能够帮你解决c – boost.proto在构建表达式树之前检测无效终端所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1230407.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存