
Kim Barrett <kab.conundrums <at> verizon.net> writes:
At 10:48 AM +0000 7/14/09, Alexander Nasonov wrote:
boost::scope_exit::aux::holder< boost::scope_exit::aux::declare< sizeof(boost_scope_exit_args)
::apply<0>::apply_value boost_scope_exit_args;
If sizeof(boost_scope_exit_args) is equal to sizeof(declared), the resulting type would be holder<(0<0>::apply_value)>. But I don't see a global variable apply_value in your patch.
The added parenthesis in the above, in
holder<(0<0>::apply_value)>
don't describe the actual parse and evaluation. Instead, that snippet gets parsed and evaluated as
holder<(0<0)>::apply_value
This is crazy, isn't it? Q: correctly indent the following code: <see code above> A: it's impossible For the second use, the correct indentation is: boost::scope_exit::aux::holder< boost::scope_exit::aux::declare< sizeof(boost_scope_exit_args)
::apply < 0 ::apply_value > boost_scope_exit_args;
BTW, I modified Steven's code and introduced a bug because sizeof(declare<sizeof(undeclared)>::apply<0>) does not necessarily equal to sizeof(declared).
Are you sure? Perhaps I'm missing something, but it looks to me like those values should indeed be the same. The "apply" class template in question has one member, of type "declared". Given that, I would be surprised if the "apply" class template could have a different size (or alignment) from the "declared" type.
They're the same because void* is well aligned and there is no padding in struct apply<0> but strictly speaking, they don't have to be of equal size. I like explicit specializations for declared and undeclared, though. They make reading code a little bit easier (and here "a little bit" make a big difference, given how complex the trick is). Perhaps adding BOOST_STATIC_ASSERT would be enough? Alex multiplied by a complec.