Boost logo

Boost Users :

From: Tim Hockin (thockin_at_[hidden])
Date: 2008-08-02 00:59:04


I use a few lambdas in my application. Simple ones like (_1 + 1) work
fine. However, when I use this next one, the compile blows up on me
and produces a huge and indecipherable error:
    if_then_else_return(_1 == 0, 64, _1)

Yields:

cc1plus: warnings being treated as errors
/usr/include/boost/lambda/if.hpp: In member function 'RET
boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::ifthenelsereturn_action>,
Args>::call(A&, B&, C&, Env&) const [with RET = const bignum&, A =
const bignum, B = const boost::tuples::null_type, C = const
boost::tuples::null_type, Env = const boost::tuples::null_type, Args =
boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::relational_action<boost::lambda::equal_action>,
boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<1>
>, const int, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type> > >, const int,
boost::lambda::lambda_functor<boost::lambda::placeholder<1> >,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type>]':
/usr/include/boost/lambda/detail/lambda_functors.hpp:148:
instantiated from 'typename T::sig<boost::tuples::tuple<A&,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type> >::type
boost::lambda::lambda_functor<Base>::operator()(A&) const [with A =
const bignum, T =
boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::ifthenelsereturn_action>,
boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::relational_action<boost::lambda::equal_action>,
boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<1>
>, const int, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type> > >, const int,
boost::lambda::lambda_functor<boost::lambda::placeholder<1> >,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type> >]'
../pp_datatypes.h:454: instantiated from 'std::string
pp_transform_datatype<Tdefunc, Tenfunc>::evaluate(const pp_value&)
const [with Tdefunc =
boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::ifthenelsereturn_action>,
boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::relational_action<boost::lambda::equal_action>,
boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<1>
>, const int, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type> > >, const int,
boost::lambda::lambda_functor<boost::lambda::placeholder<1> >,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type> > >, Tenfunc =
boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::arithmetic_action<boost::lambda::minus_action>,
boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<1>
>, const int, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type> > >]'
cpuid/generic_device.cpp:915: instantiated from here
/usr/include/boost/lambda/if.hpp:315: warning: returning reference to temporary

(this is with GCC 4.x) and _1 is a GMPXX bignum

So I tried to boil it down, and I ran into a slightly different error.
 This code:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/if.hpp>
#include <iostream>

using namespace boost::lambda;

int real_func(int x)
{
        return x+10;
}

struct functor
{
        int
        operator()(int x)
        {
                return x+20;
        }
};

template <typename T>
struct functor_templ
{
        T
        operator()(T x)
        {
                return x+30;
        }
};

template <typename T>
int
call_this(T func)
{
        return func(make_const(0));
}

int
main()
{
        int a = call_this(&real_func);
        if (a != 10) std::cerr << "a != 10" << std::endl;
        int b = call_this(functor());
        if (b != 20) std::cerr << "b != 20" << std::endl;
        int c = call_this(functor_templ<int>());
        if (c != 30) std::cerr << "c != 30" << std::endl;
        int x = call_this(_1+40);
        if (x != 40) std::cerr << "x != 40" << std::endl;
        int y = call_this(if_then_else_return(_1 == 0, 50, _1));
        return 0;
}

blows up on the if_then_else_return:

lambda_crap.cpp: In function 'int call_this(T) [with T = boost::lambda::lambda_f
unctor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lam
bda::ifthenelsereturn_action>, boost::tuples::tuple<boost::lambda::lambda_functo
r<boost::lambda::lambda_functor_base<boost::lambda::relational_action<boost::lam
bda::equal_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::la
mbda::placeholder<1> >, const int, boost::tuples::null_type, boost::tuples::null
_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_t
ype, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_typ
e> > >, const int, boost::lambda::lambda_functor<boost::lambda::placeholder<1> >
, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, bo
ost::tuples::null_type> > >]':
lambda_crap.cpp:49: instantiated from here
lambda_crap.cpp:35: error: cannot convert 'const boost::lambda::detail::return_t
ype_deduction_failure<boost::lambda::detail::return_type_2_ifthenelsereturn<1, t
rue, true, false, const int, const int&> >' to 'int' in return
/usr/include/boost/lambda/if.hpp: In member function 'RET boost::lambda::lambda_
functor_base<boost::lambda::other_action<boost::lambda::ifthenelsereturn_action>
, Args>::call(A&, B&, C&, Env&) const [with RET = const boost::lambda::detail::r
eturn_type_deduction_failure<boost::lambda::detail::return_type_2_ifthenelseretu
rn<1, true, true, false, const int, const int&> >, A = const int, B = const boos
t::tuples::null_type, C = const boost::tuples::null_type, Env = const boost::tup
les::null_type, Args = boost::tuples::tuple<boost::lambda::lambda_functor<boost:
:lambda::lambda_functor_base<boost::lambda::relational_action<boost::lambda::equ
al_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::pl
aceholder<1> >, const int, boost::tuples::null_type, boost::tuples::null_type, b
oost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boo
st::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >,
const int, boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost:
:tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::t
uples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tup
les::null_type>]':
/usr/include/boost/lambda/detail/lambda_functors.hpp:148: instantiated from 't
ypename T::sig<boost::tuples::tuple<A&, boost::tuples::null_type, boost::tuples:
:null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::n
ull_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::nul
l_type, boost::tuples::null_type> >::type boost::lambda::lambda_functor<Base>::o
perator()(A&) const [with A = const int, T = boost::lambda::lambda_functor_base<
boost::lambda::other_action<boost::lambda::ifthenelsereturn_action>, boost::tupl
es::tuple<boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost
::lambda::relational_action<boost::lambda::equal_action>, boost::tuples::tuple<b
oost::lambda::lambda_functor<boost::lambda::placeholder<1> >, const int, boost::
tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tu
ples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tupl
es::null_type, boost::tuples::null_type> > >, const int, boost::lambda::lambda_f
unctor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples:
:null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::n
ull_type, boost::tuples::null_type, boost::tuples::null_type> >]'
lambda_crap.cpp:35: instantiated from 'int call_this(T) [with T = boost::lambd
a::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action
<boost::lambda::ifthenelsereturn_action>, boost::tuples::tuple<boost::lambda::la
mbda_functor<boost::lambda::lambda_functor_base<boost::lambda::relational_action
<boost::lambda::equal_action>,
boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<1>
>, const int, boost::tuples::null_type, boost::t
uples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tup
les::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuple
s::null_type> > >, const int, boost::lambda::lambda_functor<boost::lambda::place
holder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::
null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::nu
ll_type, boost::tuples::null_type> > >]'
lambda_crap.cpp:49: instantiated from here
/usr/include/boost/lambda/if.hpp:315: error: conversion from 'const int' to non-
scalar type 'const boost::lambda::detail::return_type_deduction_failure<boost::l
ambda::detail::return_type_2_ifthenelsereturn<1, true, true, false, const int, c
onst int&> >' requested
make: *** [lambda_crap] Error 1

How can I do this? I want to write a lamba that simply says "if (_1
== 0) return 64; else return _1;

Thanks!!

Tim


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