

Self-inlining anonymous functions in C++ - adg001
http://matt.might.net/articles/self-inlining-anonymous-functions-in-c++/

======
barrkel
This is truly revolting, offensive code. Unless you like C++ template
metaprogramming, I recommend you don't look.

:)

~~~
DCoder
(Edit: fixed formatting) Revolting? I think that's a pretty good, if complex,
example of "pushing the limits". IMHO, the label "revolting" is reserved for
code like this:

    
    
      Derived() : Base() {
        THISCALL(0x535AA0);
        *(DWORD*)this = 0x7E1AF4;
      }
    

That's the kind of code I get to write in my hobby project.

~~~
barrkel
It's using the type system to encode an arithmetic expression, with unique
types for every distinct subtree; and then using statically-dispatched calls
to inlined methods to get the compiler to embed the tree in-place, so that the
optimizer's constant folding can evaluate the tree. The amount of code and
data that's being shifted around and manipulated inside the compiler to
generate a rather trivial end effect is what's offensive to me. If C++ were
slightly more expressive, the technique would be unnecessary; but some C++
acolytes actually extol these kinds of techniques as a feature!

~~~
jheriko
The technique is unnecessary, regardless as to C++ - its just a different way
to write code.

------
jheriko
This is pretty cool - the final compiled code looks pretty tidy considering
the hoops being jumped through. :)

------
slug
If you are interested in this subject, you might find the following pertinent:

<http://www.boost.org/doc/libs/1_42_0/doc/html/lambda.html>

and as someone posted here before:

<http://gcc.gnu.org/projects/cxx0x.html>

There's also an interview with a "brief" summary from Scott Meyers at
[http://www.se-
radio.net/podcast/2010-04/episode-159-c0x-scot...](http://www.se-
radio.net/podcast/2010-04/episode-159-c0x-scott-meyers) that mentions lambda
functions.

~~~
jimbokun
Wow. Things that look like expressions, but are most definitely not, through
the magic of operator overloading. So you can translate some expressions
straightforwardly, but other expressions not, with the cases for what works
and doesn't requiring careful thought.

So this works:

    
    
        for_each(vp.begin(), vp.end(), cout << *_1 << '\n');
    

This doesn't:

    
    
        for_each(vp.begin(), vp.end(), cout << '\n' << *_1);
    

But this does:

    
    
        for_each(vp.begin(), vp.end(), cout << constant('\n') << *_1);
    

Considering how complex it is to figure out what works and what doesn't in
that lambda slot, I'm not sure it's worth the effort. Of course I'm not a C++
programmer, and this is yet another reason why that might not be such a bad
thing.

(Note: this is regarding Boost lambda, if that wasn't clear.)

~~~
scott_s
_Considering how complex it is to figure out what works and what doesn't in
that lambda slot, I'm not sure it's worth the effort._

I am a C++ programmer, and that's exactly the conclusion I came to regarding
Boost's lambda. I use Boost's bind library all the time, though.

But! C++0x has real lambdas, so we won't have to resort to this trickery much
longer.

------
koblas
Feels like somebody doesn't trust #define's for their C++ code. While you
don't get the type "safety" you get something thats a bit more natural.

~~~
fadmmatt
You can't do this with #define alone. You can pass these "functions" around
arbitrarily, and it still works.

