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 + -
显示快捷键?