Jon Stewart on 18 Oct 2003 17:49:58 -0000


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [hosers-talk] ode to de morgan and his law


> Jon, can you say in 100 words or less what this does? I don't want to
> have to get boost and try it, or read the boost docs to find out.
> 
> Thus spake "Jon Stewart":
> > C++. E.g.:
> > 
> > #include <iostream>
> > #include <vector>
> > #include <iterator>
> > #include <algorithm>
> > 
> > #include <boost/lambda/lambda.hpp>
> > 
> > using namespace boost::lambda;
> > using namespace std;
> > 
> > template<class FnT>
> > class Converter {
> > public:
> > 	Converter(FnT& f) : fn(f) {}
> > 	operator int() const { return fn(); }
> > 
> > private:
> > 	FnT& fn;
> > };
> > 
> > template<class FnT>
> > auto_ptr< Converter<FnT> > MakeConverter(FnT& f)
> > {
> > 	auto_ptr< Converter<FnT> > ptr(new Converter<FnT>(f));
> > 	return ptr;
> > }
> > 
> > int main(int argc, char *argv[])
> > {
> > 	vector<int> vec;
> > 	int i(0);
> > 	fill_n(back_inserter(vec), 20, *MakeConverter(var(i)++));
> > 	for_each(vec.begin(), vec.end(), cout << _1 << '\n');
> > 
> > 	return EXIT_SUCCESS;
> > }
> > 
> > It's cool shit.


The include of boost/lambda.hpp turns the expression "var(i)++" into a 
functor (a class with operator() overloaded), which returns the value of i 
and post-increments it. This functor, a horribly complicated 
template, is passed into the MakeConverter() function which gets 
specialized on the type of the functor, and creates a specialized 
Converter object, throws it in an auto_ptr to prevent a memory leak.

We then dereference the auto_ptr and the Converter object gets passed into 
std::fill_n. fill_n() takes an output iterator, a number, and a value, and 
assigns the value to the iterator and incs it, for the number of times 
specified (20).

Now, the output iterator we've created with back_inserter is one that 
calls push_back() on the vector of ints, so we're filling the vector with 
ints. But wait, you say, how can you assign a 
Converter<boost::lambda::functor<blah, blah, blah, blah, blah, blah< blech 
> > > to an int? Simple: Converter provides operator int(), the implicit 
conversion operator. So any time you treat a Converter as an int, that 
function will get called.

IN OTHER WORDS, BY USING CONVERSION OPERATORS, THERE IS INDEED A WAY TO
KNOW WHEN AN OBJECT IS BEING TREATED AS AN R-VALUE.

In this example, Converter<>::operator int() returns the return value of 
the functor.

The for_each uses boost::lambda (the _1) to output every item in the 
vector. So, the program prints:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

And, by side-effect, i == 20.

Sorry, it's a bit more than 100 words, but there's a lot going on.

You should get boost. It's good shit. How does a Lisp programmer get a 
job? He learns boost.



Jon
-- 
Jon Stewart                                 Advanced Los Angeles C++
stew1@xxxxxxxxxxx                           http://www.alacpp.org
_______________________________________________
hosers-talk mailing list
hosers-talk@xxxxxxxxxxx
http://lists.ellipsis.cx/mailman/listinfo/hosers-talk