Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::proto user guide - compile error creating a lazy function
From: Eric Niebler (eric_at_[hidden])
Date: 2009-09-20 11:05:11


Hi Tom, comments inline ...

Tom Babbin wrote:
> Hi,
>
> I am going through proto user guide. I am getting compiling error for the
> following piece code (it's pretty much copy and pasted from the guide). I
> used 1.40 and gcc.
>
> #include <iostream>
> #include <boost/mpl/int.hpp>
> #include <boost/proto/core.hpp>
> #include <boost/proto/context.hpp>
> #include <boost/proto/debug.hpp>
> #include <cmath>
> #include <vector>
>
> namespace proto = boost::proto;
>
> template<int I> struct placeholder {};
>
> // Define some placeholders
> proto::terminal< placeholder< 1 > >::type const _1 = {{}};
> proto::terminal< placeholder< 2 > >::type const _2 = {{}};
>
> struct calculator_context
> : proto::callable_context< calculator_context const >
> {
> // Values to replace the placeholders
> std::vector<double> args;
>
> // Define the result type of the calculator.
> // (This makes the calculator_context "callable".)
> typedef double result_type;
>
> // Handle the placeholders:
> template<int I>
> double operator()(proto::tag::terminal, placeholder) const

Should be placeholder<I> here ----------------^^^^^^^^^^^

> {
> return this->args[I];
> }
> };
>
> // Define a pow_fun function object
> template<int Exp>
> struct pow_fun
> {
> typedef double result_type;
> double operator()(double d) const
> {
> return std::pow(d, Exp);
> }
> };
>
> // Define a lazy pow() function for the calculator DSEL.
> // Can be used as: pow< 2 >(_1)
> template<int Exp, typename Arg>
> typename proto::function<
> typename proto::terminal<pow_fun<Exp> >::type
> , Arg const &
> > ::type

Return type needs a const.

> pow1(Arg const &arg)
> {
> typedef
> typename proto::function<
> typename proto::terminal<pow_fun<Exp> >::type
> , Arg const &
> >::type
> result_type;
>
> result_type result = {{{}}, arg};
> return result;
> }
>
> int main()
> {
> calculator_context ctx;
> ctx.args.push_back(3);
>
> std::cout << boost::proto::eval( pow1<2>( _1 ), ctx );

The problem is that proto::eval() takes its first argument by non-const
reference. The temporary expression returned by pow1 doesn't bind to it
as it's defined in the users' guide. Adding a const-qualification to the
return type solves the problem.

I'll update the docs for 1.41. Thanks for the report.

-- 
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