
Boost : 
From: Jaap Suter (J.Suter_at_[hidden])
Date: 20020918 16:27:10
Hello,
consider the following code:
apply_if< some_condition,
some_type_1,
some_type_2
>::type
We do this because we don't want some_type_2 evaluated if some_condition is
true, or vice versa. Very handy and I need it a lot. However, consider the
following case:
apply_if< some_condition,
some_type_1,
plus< some_type_2::type, some_number >
>::type
In this case, I get the impression that my compiler (Intel) evaluates the
template parameters of plus, and thus of some_type_2::type, even when it is
not used. However, as in the mpl::apply_if rationale, this may not always
work.
Thus, I provide the following indirection:
template< ... >
struct recurse
{
typedef plus< some_type_2::type, some_number > type
};
apply_if< some_condition,
some_type_1,
recurse
>::type
And now it works, because the compiler no longer evaluates the
some_type_2::type, if it is not needed.
Now, I have the following questions:
1. Can you acknowledge this problem? The fact that the compiler evaluates
template parameters for nonused types, and consequently that the
mpl::apply_if
rationale applies here as well?
2. Is this the best solution to solve this problem?
3. Maybe we can introduce the indirection in plus and other metafunctions
that act on integral constants directly. Allow me to explain:
integral_c and the other (bool_c, int_c, etc.) all support the ::type
construct that reflects upon itself. We can use this to allow plus (for
example) to always query its arguments for the type.
Current mpl::plus implementation:
template< typename A, typename B >
struct plus
{
typedef integral_c< A::value_type, A::value + B::value > type;
}
My proposed mpl::plus implementation:
template< typename A, typename B >
struct plus
{
typedef integral_c< A::type::value_type, A::type::value + B::type::value
> type;
}
This allows us to pass unfinished expressions into metafunctions. A sort of
lazy evaluation. Using this, my second code example could have been written
as:
apply_if< some_condition,
some_type_1,
plus< some_type_2, some_number >
>::type
and would have worked.
However, I agree that this is a bit ugly. For example, why limit this to
only one type depth? Why not call ::type on the incoming parameters until
we reach a type that has a ::value parameter? I don't know. Perhaps my
suggested workaround using the recurse helpermetafunction is better.
Anyway, just some questions, comments and ideas....
Thanks and regards,
Jaap Suter
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk