lambda

N

Noah Roberts

template < typename T >
typename T::const_iterator first_pipe(T const& cont)
{
namespace l = boost::lambda;
typedef esi::metafunc::dereference_type<typename T::value_type>::type
value_type; // value type is mock_pipe_base in this case.

return std::find_if(cont.begin(), cont.end(),
l::bind(&value_type::GetType, *(l::_1)) == DT_PIPE);
}

struct mock_pipe_base
{
bool pipe;
mock_pipe_base(bool b) : pipe(b) {}
DT_TYPE GetType() const {
return pipe ? DT_PIPE : DT_PUMP;
}
virtual void f() = 0;
};

struct mock_pipe : mock_pipe_base
{
mock_pipe(bool b) : mock_pipe_base(b) {}
void f() {}
};



typedef std::list<mock_pipe_base*> list1_t;
list1_t l;
l.push_back(list1_t::value_type(new mock_pipe(false)));
l.push_back(list1_t::value_type(new mock_pipe(false)));
l.push_back(list1_t::value_type(new mock_pipe(false)));

list1_t::const_iterator fit = first_pipe(l);


This results in an attempt to instantiate a mock_pipe_base object,
which is of course not possible.

I can provide the real error if desired but it is quite lengthy. It
definately has something to do with the lambda expression. I'm hoping
someone will be able to look at that and know what I'm doing wrong and
be able to provide a solution. I'm about to disallow use of lambda in
our projects but I would like to come up with a solution and leave it
open with some guidelines for use.

Thanks.
 
N

Noah Roberts

I've created the problem in slightly simpler code:

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

struct test_b
{
test_b() { std::cerr << "test_b::test_b()\n"; }
test_b(test_b const&) { std::cerr << "test_b::test_b(test_b
const&)\n"; }
virtual int f() = 0; //{ return 5; }

};

struct test_d : test_b
{
test_d() : test_b() { std::cerr << "test_d::test_d()\n"; }
test_d(test_d const& d) : test_b(d) { std::cerr <<
"test_d::test_d(test_d const&)\n"; }
int f() { return 5; }
};

int main(void)
{
namespace l = boost::lambda;

test_b & td = test_d();

std::cerr << "Value: " <<
(l::bind(&test_b::f, l::_1))(td) << "\n";

int x; std::cin >> x;
}


Same error message. I'm beginning to think that lambda simply can't
handle polymorphic types at all....which makes it almost 100% useless.
 
G

Greg Buchholz

Noah said:
Same error message. I'm beginning to think that lambda simply can't
handle polymorphic types at all....which makes it almost 100% useless.

This may not help your particular situation, but changing from
references to pointers seems to work...

//test_b & td = test_d();
test_b *td = new test_d();

Greg Buchholz
 
N

Noah Roberts

Greg said:
This may not help your particular situation, but changing from
references to pointers seems to work...

//test_b & td = test_d();
test_b *td = new test_d();

Yeah, that doesn't help as it doesn't allow me to work with smart
pointers.
 
K

Kai-Uwe Bux

Noah said:
I've created the problem in slightly simpler code:

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

struct test_b
{
test_b() { std::cerr << "test_b::test_b()\n"; }
test_b(test_b const&) { std::cerr << "test_b::test_b(test_b
const&)\n"; }
virtual int f() = 0; //{ return 5; }

};

struct test_d : test_b
{
test_d() : test_b() { std::cerr << "test_d::test_d()\n"; }
test_d(test_d const& d) : test_b(d) { std::cerr <<
"test_d::test_d(test_d const&)\n"; }
int f() { return 5; }
};

int main(void)
{
namespace l = boost::lambda;

test_b & td = test_d();

Do you really want to bind a temporary to a non-const reference? My compiler
complained.
std::cerr << "Value: " <<
(l::bind(&test_b::f, l::_1))(td) << "\n";

int x; std::cin >> x;
}


Same error message. I'm beginning to think that lambda simply can't
handle polymorphic types at all....which makes it almost 100% useless.

I think the problem is that you pass td by value. At that point type
information is lost. Maybe using ref() helps, e.g.:

#include <iostream>
#include <tr1/functional>

struct test_b
{
test_b() { std::cerr << "test_b::test_b()\n"; }
test_b(test_b const&)
{ std::cerr << "test_b::test_b(test_b const&)\n"; }
virtual int f() = 0; //{ return 5; }

virtual ~test_b () {}
};

struct test_d : test_b
{
test_d() : test_b()
{ std::cerr << "test_d::test_d()\n"; }
test_d(test_d const& d) : test_b(d)
{ std::cerr << "test_d::test_d(test_d const&)\n"; }
int f() { return 5; }
};

int main(void)
{
test_d td;
test_b & tb = td;
std::cerr << "Value: " <<
(std::tr1::bind(&test_b::f, std::tr1::ref(tb)))() << "\n";
}


Best

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top