construction.qbk

来自「Boost provides free peer-reviewed portab」· QBK 代码 · 共 1,026 行 · 第 1/3 页

QBK
1,026
字号
    [`negate<>`]]    [[unary `*`]    [`tag::dereference`]    [`dereference<>`]]    [[unary `~`]    [`tag::complement`]    [`complement<>`]]    [[unary `&`]    [`tag::address_of`]    [`address_of<>`]]    [[unary `!`]    [`tag::logical_not`]    [`logical_not<>`]]    [[unary prefix `++`]    [`tag::pre_inc`]    [`pre_inc<>`]]    [[unary prefix `--`]    [`tag::pre_dec`]    [`pre_dec<>`]]    [[unary postfix `++`]    [`tag::post_inc`]    [`post_inc<>`]]    [[unary postfix `--`]    [`tag::post_dec`]    [`post_dec<>`]]    [[binary `<<`]    [`tag::shift_left`]    [`shift_left<>`]]    [[binary `>>`]    [`tag::shift_right`]    [`shift_right<>`]]    [[binary `*`]    [`tag::multiplies`]    [`multiplies<>`]]    [[binary `/`]    [`tag::divides`]    [`divides<>`]]    [[binary `%`]    [`tag::modulus`]    [`modulus<>`]]    [[binary `+`]    [`tag::plus`]    [`plus<>`]]    [[binary `-`]    [`tag::minus`]    [`minus<>`]]    [[binary `<`]    [`tag::less`]    [`less<>`]]    [[binary `>`]    [`tag::greater`]    [`greater<>`]]    [[binary `<=`]    [`tag::less_equal`]    [`less_equal<>`]]    [[binary `>=`]    [`tag::greater_equal`]    [`greater_equal<>`]]    [[binary `==`]    [`tag::equal_to`]    [`equal_to<>`]]    [[binary `!=`]    [`tag::not_equal_to`]    [`not_equal_to<>`]]    [[binary `||`]    [`tag::logical_or`]    [`logical_or<>`]]    [[binary `&&`]    [`tag::logical_and`]    [`logical_and<>`]]    [[binary `&`]    [`tag::bitwise_and`]    [`bitwise_and<>`]]    [[binary `|`]    [`tag::bitwise_or`]    [`bitwise_or<>`]]    [[binary `^`]    [`tag::bitwise_xor`]    [`bitwise_xor<>`]]    [[binary `,`]    [`tag::comma`]    [`comma<>`]]    [[binary `->*`]    [`tag::mem_ptr`]    [`mem_ptr<>`]]    [[binary `=`]    [`tag::assign`]    [`assign<>`]]    [[binary `<<=`]    [`tag::shift_left_assign`]    [`shift_left_assign<>`]]    [[binary `>>=`]    [`tag::shift_right_assign`]    [`shift_right_assign<>`]]    [[binary `*=`]    [`tag::multiplies_assign`]    [`multiplies_assign<>`]]    [[binary `/=`]    [`tag::divides_assign`]    [`divides_assign<>`]]    [[binary `%=`]    [`tag::modulus_assign`]    [`modulus_assign<>`]]    [[binary `+=`]    [`tag::plus_assign`]    [`plus_assign<>`]]    [[binary `-=`]    [`tag::minus_assign`]    [`minus_assign<>`]]    [[binary `&=`]    [`tag::bitwise_and_assign`]    [`bitwise_and_assign<>`]]    [[binary `|=`]    [`tag::bitwise_or_assign`]    [`bitwise_or_assign<>`]]    [[binary `^=`]    [`tag::bitwise_xor_assign`]    [`bitwise_xor_assign<>`]]    [[binary subscript]    [`tag::subscript`]    [`subscript<>`]]    [[ternary `?:`]    [`tag::if_else_`]    [`if_else_<>`]]    [[nary function call]    [`tag::function`]    [`function<>`]]][endsect][/===========================================================][section:construction_utils Expression Construction Utilities][/===========================================================]Proto gives you many other ways of creating expression trees besides the operatoroverloads. These are useful for building nodes with custom tag types that don'tcorrespond to any C++ operator. They're also useful when writing tree transformsthat manipulate the structure of the expression tree, as we'll see.Below are the tools and a brief description of each.[variablelist[ [_make_expr_]  [A function that takes a tag type and children nodes and   builds a parent node of the requested type.]][ [_unpack_expr_]  [A function that does the same as _make_expr_ except   the children nodes are specified as a Fusion sequence.]][ [`BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE()`]  [A macro that generates a number of overloads of a   user-specified function template that behaves like   _make_expr_.]]][/====================================================][heading Building Expression Trees With [^make_expr()]][/====================================================][:[*Synopsys:]]    namespace proto    {        namespace result_of        {            // Metafunction for calculating the return type            // of the make_expr() function            template<                typename Tag              , typename DomainOrArg              , typename... A            >            struct make_expr            {                typedef __implelemtation_defined__ type;            };        }        namespace functional        {            // A callable function object equivalent of the            // make_expr() function.            template<typename Tag, typename Domain = default_domain>            struct make_expr : callable            {                template<typename Sig> struct result;                template<typename This, typename... A>                struct result<This(A...)>                  : result_of::make_expr<Tag, Domain, A...>                {};                template<typename... A>                typename result_of::make_expr<Tag, Domain, const A...>::type                operator ()(A const &... a) const;            };        }        // The make_expr() function        template<typename Tag, typename Domain, typename... A>        typename result_of::make_expr<Tag, Domain, A...>::type        make_expr(A const &... a);    }You can use the _make_expr_ function to build an expression tree node witha specified tag type, as follows.    // Some user-defined tag type    struct MyTag {};        // Construct a node with MyTag tag type, and    // two terminals as children.    int i = 0;    proto::make_expr<MyTag, default_domain>(i, 'a');You are not required to specify a domain. If you choose not to, `default_domain`is assumed. So the above is equivalent to:    // Construct a node with MyTag tag type, and    // two terminals as children.    int i = 0;    proto::make_expr<MyTag>(i, 'a');The return type of the above function invocation can be calculated with the`result_of::make_expr<>` metafunction.    // Use result_of::make_expr<> to compute the return type:    int i = 0;    typedef        proto::result_of::make_expr<            MyTag          , int          , char        >::type    expr_type;    expr_type expr = proto::make_expr<MyTag>(i, 'a');    // expr_type is the same as this type:    typedef        proto::binary_expr<            MyTag          , proto::terminal<int>::type          , proto::terminal<char>::type        >::type    expr_type2;        BOOST_MPL_ASSERT((is_same<expr_type2, expr_type>));Notice that the children, an int and a char, are wrapped in terminalnodes and held by value. If you would like an argument to be beld by reference in the resulting tree node, you can use `boost::ref()`:    // One terminal held by reference:    int i = 0;    typedef        proto::result_of::make_expr<            MyTag          , int &   // <-- Note reference here          , char        >::type    expr_type;    expr_type expr = proto::make_expr<MyTag>(boost::ref(i), 'a');In the return type calculation, we can specify by-ref with `int &`, but we need `boost::ref()` in the actual function invocation.That's because the _make_expr_ function can't tell from the functionarguments whether you want to store the arguments by value or byreference.Non-terminals are handled similarly. Given the non-terminal `expr` as defined above, we could wrap it in a unary plus node by value or by reference as follows:    // Make "expr" a child node of a new unary plus node, where    // "expr" is held by-value:    typedef        proto::result_of::make_expr<            proto::tag::posit          , expr_type        >::type    posit_val_type;    posit_val_type p1 = proto::make_expr<proto::tag::posit>(expr);    // Same as above, except "expr" is held by-reference:    typedef        proto::result_of::make_expr<            proto::tag::posit          , expr_type &     // <-- Note reference here        >::type    posit_ref_type;    posit_ref_type p2 = proto::make_expr<proto::tag::posit>(boost::ref(expr));    // Equivalent to "by-ref" line directly above:    posit_ref_type p3 = +expr;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?