почему два результата оценки отличаются в терминале Boost Yap? - PullRequest
0 голосов
/ 05 февраля 2020

Я хочу использовать boost yap, чтобы сделать несколько небольших примеров, код приведен ниже, я поместил выражение в оператор или функцию-член в структуру,

expn_n, результат равен 3, это правильно. Но Результат exp_n равен -1.85119e + 62 странное число.

Почему два результата оценки отличаются?

#include <boost/yap/algorithm.hpp>
#include <array>
#include <iostream>

struct wrapper {
    wrapper() {}
    wrapper(double i) :i_(i) {}
    double operator ()(double a, double b) const
    {
        return (a + b) * i_;
    }
    double i_;
    double a_;
    double b_;
};
template <boost::yap::expr_kind Kind, typename Tuple>
struct tarray_expr;


struct take_nth
{
    boost::yap::terminal<tarray_expr, double>
        operator() (boost::yap::terminal<tarray_expr, wrapper> const & expr);

    double a;
    double b;
};


template <boost::yap::expr_kind Kind, typename Tuple>
struct tarray_expr
{
    static const boost::yap::expr_kind kind = Kind;

    Tuple elements;

    auto operator() (double a, double b) const
    {
        return boost::yap::evaluate(boost::yap::transform(*this, take_nth{ a,b }));
    }
};

// Define operators +, -, *, and /.
BOOST_YAP_USER_BINARY_OPERATOR(plus, tarray_expr, tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR(minus, tarray_expr, tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR(multiplies, tarray_expr, tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR(divides, tarray_expr, tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR(bitwise_xor, tarray_expr, tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR(logical_or, tarray_expr, tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR(equal_to, tarray_expr, tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR(not_equal_to, tarray_expr, tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR(greater, tarray_expr, tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR(less, tarray_expr, tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR(less_equal, tarray_expr, tarray_expr)
BOOST_YAP_USER_BINARY_OPERATOR(greater_equal, tarray_expr, tarray_expr)
BOOST_YAP_USER_EXPR_IF_ELSE(tarray_expr);


boost::yap::terminal<tarray_expr,double>
take_nth::operator() (boost::yap::terminal<tarray_expr, wrapper> const & expr)
{
    double x = boost::yap::value(expr)(a, b);
    return boost::yap::make_terminal<tarray_expr>(std::move(x));
}

struct tarray :
    tarray_expr<
    boost::yap::expr_kind::terminal,
    boost::hana::tuple<wrapper>
    >
{
    explicit tarray() {}

    explicit tarray(wrapper && a)
    {
        elements = boost::hana::tuple<wrapper>(std::move(a));
    }

    double  operator() (double a, double b)
    {
        return boost::yap::value(*this)(a,b);
    }

    double const  operator() (double a, double b) const
    {
        return boost::yap::value(*this)(a,b);
    }

    template <boost::yap::expr_kind Kind, typename Tuple>
    tarray & operator=(tarray_expr<Kind, Tuple> const & t)
    {
        return assign(t);
    }

    template <boost::yap::expr_kind Kind, typename Tuple>
    tarray & printAssign(tarray_expr<Kind, Tuple> const & expr)
    {
        *this = expr;
        return *this;
    }

private:
    template <typename Expr>
    tarray&  assign(Expr const & expr)
    {
        return *this;
    }
};

struct eval 
{
    auto operator() (double a, double b) {
        auto lhs_w = boost::yap::make_terminal<tarray_expr>(std::move(a));
        auto rhs_w = boost::yap::make_terminal<tarray_expr>(std::move(b));

        return lhs_w + rhs_w;
    }
};

int main()
{
    //----eval test
    eval ev;
    auto exp_n = ev(1.0, 2.0);
    auto rs = boost::yap::evaluate(exp_n);
    std::cout << "exp_n is: " << rs << std::endl;
    // without function structure
    auto lhs = boost::yap::make_terminal<tarray_expr>(std::move(1.0));
    auto rhs = boost::yap::make_terminal<tarray_expr>(std::move(2.0));
    auto expn_n = lhs + rhs;
    auto rs_n = boost::yap::evaluate(expn_n);
    std::cout << "expn_n is: " << rs_n << std::endl;

    system("pause");
    return 0;
}
...