![]() |
Home | Libraries | People | FAQ | More |
When you build an expression template with Proto, all the intermediate
child nodes are held by reference. The avoids needless
copies, which is crucial if you want your EDSL to perform well at runtime.
Naturally, there is a danger if the temporary objects go out of scope before
you try to evaluate your expression template. This is especially a problem
in C++0x with the new decltype
and auto
keywords. Consider:
// OOPS: "ex" is left holding dangling references auto ex = proto::lit(1) + 2;
The problem can happen in today's C++ also if you use BOOST_TYPEOF()
or BOOST_AUTO()
, or if you try to pass an expression
template outside the scope of its constituents.
In these cases, you want to deep-copy your expression template so that
all intermediate nodes and the terminals are held by value.
That way, you can safely assign the expression template to a local variable
or return it from a function without worrying about dangling references.
You can do this with proto::deep_copy()
as fo llows:
// OK, "ex" has no dangling references auto ex = proto::deep_copy( proto::lit(1) + 2 );
If you are using Boost.Typeof, it would look like this:
// OK, use BOOST_AUTO() and proto::deep_copy() to // store an expression template in a local variable BOOST_AUTO( ex, proto::deep_copy( proto::lit(1) + 2 ) );
For the above code to work, you must include the boost/proto/proto_typeof.hpp
header, which also defines the
macro which automatically deep-copies its argument. With BOOST_PROTO_AUTO
()
, the above
code can be writen as:
BOOST_PROTO_AUTO
()
// OK, BOOST_PROTO_AUTO() automatically deep-copies // its argument: BOOST_PROTO_AUTO( ex, proto::lit(1) + 2 );
When deep-copying an expression tree, all intermediate nodes and all terminals are stored by value. The only exception is terminals that are function references, which are left alone.
![]() |
Note |
---|---|
|