|
Boost Users : |
Subject: Re: [Boost-users] [Proto] Questions about deep_copy
From: Eric Niebler (eric_at_[hidden])
Date: 2009-05-10 11:48:29
Kim Kuen Tang wrote:
> Hi all,
>
> consider the following code:
>
> std::vector<double> a(10,1.0), b(10,2.0);
> BOOST_AUTO( temp , proto::as_expr<MixedDomain>(a+b+0.1) ); // is the
> function proto::as_expr<MixedDomain>() needed?
<snip>
>
> But the code crashes during runtime. The reason is that the number 0.1
> is held by reference.
> So the number 0.1 goes out of scope before i try to evaluate the
> expression temp[0];
>
> A way to solve this problem is to deep copy the expression with
> deep_copy. But on the other hand i do not want to copy the two vectors a
> and b.
Deep-copying only some terminals is fundamentally unsafe. But if you
really don't want to deep-copy the vector terminals, you'll need to
implement your own deep-copy algorithm. It's easiest to write a grammar
with transforms that does it for you.
#include <vector>
#include <boost/proto/proto.hpp>
namespace boost { namespace proto
{
// make std::vector a proto terminal extension
template<typename T, typename Al>
struct is_extension<std::vector<T, Al> >
: mpl::true_
{};
}}
namespace proto = boost::proto;
using proto::_;
// Deep-copy all terminals except vectors
struct DeepCopyNotVectors
: proto::or_<
proto::when<
proto::terminal<std::vector<_,_> >
// The vector itself will be held by reference, but the
// temporary proto terminal expression wrapping the
// reference should be held by value.
, boost::remove_const<boost::remove_reference<_> >(_)
>
, proto::when<proto::terminal<_>, proto::_deep_copy(_)>
, proto::otherwise<
proto::nary_expr<_, proto::vararg<DeepCopyNotVectors> >
>
>
{};
int main()
{
using namespace proto::exops;
std::vector<int> a, b;
BOOST_AUTO(tmp0, a + b + 0.1);
BOOST_AUTO(tmp1, DeepCopyNotVectors()(a + b + 0.1));
std::cout << typeid(tmp0).name() << "\n\n";
std::cout << typeid(tmp1).name() << "\n";
}
int main()
{
using namespace proto::exops;
std::vector<int> a, b;
BOOST_AUTO(tmp0, a + b + 0.1);
BOOST_AUTO(tmp1, DeepCopyNotVectors()(a + b + 0.1));
std::cout << typeid(tmp0).name() << "\n\n";
std::cout << typeid(tmp1).name() << "\n";
}
-- Eric Niebler BoostPro Computing http://www.boostpro.com
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net