|
Boost Users : |
From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2005-10-04 23:22:41
Geoffrey Romer writes:
> I'm struggling with a problem of how to correctly use conditionals in
> MPL. In a nutshell, the problem is that the compiler greedily
> evaluates all parts of a conditional, even the branch that isn't
> followed. This is a problem not just for performance, but because
> sometimes the unused branch might not compile.
>
> I know that eval_if is supposed to address this problem, but unless
> I'm missing something, it doesn't seem to be a complete solution. It
> delays evaluating the branches until one of them is selected, but the
> compiler still evaluates the *arguments* to both branches. If the
> arguments themselves don't compile, I'm screwed, despite the fact that
> the parts of my code that are actually relevant (the branches that get
> used) are perfectly correct.
Correct.
>
> How do I resolve this problem?
The most straightforward solution is to factor out the computation
into a separate auxiliary metafunction...
>
> Here's a toy example, a metafunction which, given a map, finds the
> value associated with the key "char" and, if it exists, increments the
> associated value (which we assume is numeric):
>
> template <typename m_map>
> class toy_metafunction
> {
> typedef typename
> if_<typename has_key<m_map, char>::type,
> typename insert<m_map, pair<char,
> typename plus<int_<1>,
> at<m_map, char>
> >::type
> >
> >::type,
> m_map
> >::type type;
> };
... like this:
template< typename Map, typename Key >
struct increment_key_counter
: insert<
Map
, pair<
Key
, typename plus< int_<1>, typename at<Map,Key>::type >::type
>
{
};
template< typename Map >
struct toy_metafunction
: eval_if<
typename has_key<Map, char>::type
, increment_key_counter<Map, char>
, identity<Map>
>
{
};
-- Aleksey Gurtovoy MetaCommunications Engineering
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net