
David Abrahams wrote:
You're passing a predicate nullary metafunction to the library and asking MPL to invoke it. It's sort of like, at runtime,
int f(int, int); # akin to mpl::equal
template <class NullaryFunction> int invoke(NullaryFunction g) { return g(); }
int result = invoke( boost::bind(f, 3, 5) ); ^^^^^^^^^^^^^^^^^^^^ the nullary function, akin to mpl::equal<mpl::set<A,B>, mpl::set<A,B> >
I find it a lot easier to understand if I focus on the fact that, unlike runtime asserts, which conceptually take boolean values, BOOST_MPL_ASSERT takes a function, which it itself invokes. This is, to me, a *major* change. It's the difference between bool f(); // some function assert( f() ); // the way asserts work now assert( f ); // the way asserts would work if they worked like MPL asserts I think a lot of the trouble I have is due to a lack of documentation explaining the differences between what I'm used to with runtime C++ and how MPL does things. IME, it's not that the MPL documentation is incorrect, it's just that the reference manual is, well, a reference manual. So I skim over the fact that BOOST_MPL_ASSERT takes a metafunction, because I'm thinking, "I already know how asserts work." But I *don't* know how MPL asserts work, because they use a completely different conceptual model, yet they use the same vocabulary. I'm not blaming the reference manual here. It does what it should do. And I'm not blaming your book. But note in your book how on page 160 you show that BOOST_STATIC_ASSERT takes an *expression* and on page 162 you show how BOOST_MPL_ASSERT takes a *metafunction*, yet the only thing you explicitly call the reader's attention to is the need for double parentheses in the MPL assert. At least in my case, it was really easy to fail to note the shift from an expression (what I was used to) to a function (quite a different thing). Scott