Boost logo

Boost Users :

Subject: [Boost-users] proto user guide e.g.
From: Hicham Mouline (hicham_at_[hidden])
Date: 2009-02-23 14:52:03


Hi, continuing to work through the user guide
boost_1_38_0/doc/html/proto/users_guide.html,
I reached the section Retaining POD-ness with BOOST_PROTO_EXTENDS()

I fail to compile the following code with intel10:

--------------------------CODE-----------------------------
#include <iostream>
#include <vector>
#include <cmath>
#include <boost/proto/core.hpp>
#include <boost/proto/tags.hpp>
#include <boost/proto/context.hpp>
#include <boost/proto/domain.hpp>
#include <boost/mpl/assert.hpp>

using namespace boost;
// Define a placeholder type
template<int I>
struct placeholder
{};

// A type to be used as a domain tag (to be defined below)
struct calculator_domain;

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<I>) const
    {
        return this->args[I];
    }
};

// The calculator<> expression wrapper makes expressions
// function objects.
template< typename Expr>
struct calculator
{
    // Use BOOST_PROTO_BASIC_EXTENDS() instead of proto::extends<> to
    // make this type a Proto expression extension:
    BOOST_PROTO_BASIC_EXTENDS(Expr, calculator<Expr>, calculator_domain)

    // Define operator[] to build expression templates:
    BOOST_PROTO_EXTENDS_SUBSCRIPT()

    // Define operator= to build expression templates:
    BOOST_PROTO_EXTENDS_ASSIGN()

    typedef double result_type;

    // Hide base_type::operator() by defining our own which
    // evaluates the calculator expression with a calculator context.
    result_type operator()( double d1 = 0.0, double d2 = 0.0 ) const
    {
        // As defined in the Hello Calculator section.
        calculator_context ctx;

        // ctx.args is a vector<double> that holds the values
        // with which we replace the placeholders (e.g., _1 and _2)
        // in the expression.
        ctx.args.push_back( d1 ); // _1 gets the value of d1
        ctx.args.push_back( d2 ); // _2 gets the value of d2

        return proto::eval(*this, ctx ); // evaluate the expression
    }
};

// Define a calculator domain. Expression within
// the calculator domain will be wrapped in the
// calculator<> expression wrapper.
struct calculator_domain
  : proto::domain< proto::generator<calculator> >
{};

int main()
{
  calculator< proto::terminal< placeholder<0> >::type > const _1 = {{{}}};
  calculator< proto::terminal< placeholder<1> >::type > const _2 = {{{}}};

  std::cout << ((_1 + _2)(45., 56.)) << std::endl;
}
-------------------------------- END CODE --------------------------------

The error is:
1>using typeof emulation
1>C:\Program Files (x86)\boost_1_38_0\boost/proto/generate.hpp(153): error:
no suitable user-defined conversion from "const
boost::proto::exprns_::expr<boost::proto::tag::plus,
boost::proto::argsns_::list2<const
calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<placeholder<0>>, 0L>> &, const
calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<placeholder<1>>, 0L>> &>, 2L>" to
1> "calculator<boost::proto::exprns_::expr<boost::proto::tag::plus,
boost::proto::argsns_::list2<const
calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<placeholder<0>>, 0L>> &, const
calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<placeholder<1>>, 0L>> &>, 2L>>" exists
1> return Extends<Expr>(expr);
1> ^
1> detected during:
1> instantiation of "Extends<Expr>
boost::proto::generatorns_::generator<Extends>::operator()(const Expr &)
const [with Extends=calculator,
Expr=boost::proto::exprns_::expr<boost::proto::tag::plus,
boost::proto::argsns_::list2<const
calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<placeholder<0>>, 0L>> &, const
calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<placeholder<1>>, 0L>> &>, 2L>]" at
1> line 145 of "C:\Program Files
(x86)\boost_1_38_0\boost/proto/operators.hpp"
1> instantiation of "Left::proto_domain::result<void
(boost::proto::exprns_::expr<Tag, boost::proto::argsns_::list2<Left &, Right
&>, boost::proto::argsns_::list2<Left &, Right &>::arity>)>::type
boost::proto::detail::as_expr_if<Tag, Left, Right, Left::proto_is_expr_,
Right::proto_is_expr_>::make(Left &, Right &) [with
Tag=boost::proto::tag::plus, Left=const
calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<placeholder<0>>, 0L>>,
1> Right=const
calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<placeholder<1>>, 0L>>]" at line 290 of
"C:\Program Files (x86)\boost_1_38_0\boost/proto/operators.hpp"
1> instantiation of "const
boost::proto::detail::as_expr_if<boost::proto::tag::plus, const Left, const
Right, void, void>::type boost::proto::exprns_::operator+(const Left &,
const Right &) [with
Left=calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<placeholder<0>>, 0L>>,
Right=calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<placeholder<1>>, 0L>>]" at line 120 of
".\Test4.cpp"
1>
1>compilation aborted for .\Test4.cpp (code 2)


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