Re: [Boost-users] Using MPL for conditional compilation
----- Mensaje original -----
De: "Alan M. Carroll"
I am building a templated container class C. Normally it acts just like an stl::map. However, if the mapped_type of a container C
is also a specialization of C (value1 = C ) then the key types of the containers are merged in to a tuple yielding a container that acts like C< , value2 >. Obviously the MPL has been quite useful for this but I'm not clear on the best style / usage for a particular effect.
Inside C, the insert method has two parts, the part that's the same regardless of whether C is merged container and the part that isn't. How should I arrange to have different code executed depending on whether C is a merged container or not? I have a class static const bool IS_OUTER that is set to true for merged containers and false otherwise.
[...]
5) Use traits classes keyed by IS_OUTER to provide the differing implementations.
If the *syntactic* differences between both flavors can
be reduced to only different definitions for key_type and
mapped_type, I'd use something like your option 5) :
template
::type flavor;
public:
typedef typename boost::mpl::if_c<
IS_OUTER,
boost::tuple
::type key_type;
typedef typename boost::mpl::if_c< IS_OUTER, typename Value::mapped_type, Value
::type mapped_type;
// example of memfun with alternate implementations const_iterator find(const key_type& k)const { return find_impl(k,flavor()); } // shared menfuns do not need any special machinery private: // alternate implementations of find const_iterator find_impl(const key_type& k,outer_tag)const { ... } const_iterator find_impl(const key_type& k,inner_tag)const { ... } }; With this scaffolding set up, it is guaranteed that only the appropriate *_impl memfuns are compiled in each case, and the runtime penalty should be optimized away to zero. OTOH, if the number of memfuns with alternate implementations is very large with respect to shared memfuns, you might want to go for fully separated classes. HTH, Joaquín M López Muñoz Telefónica, Investigaión y Desarrollo
Alan M. Carroll wrote:
I must be missing something obvious, or Boost.Mpl doesn't work on MSVC 7.1.
I'm working on my container class C
. Using MPL I've defined a class static bool IS_OUTER which, if true, means that PAYLOADhas a typedef for the name "key_type". If IS_OUTER is false, then PAYLOADmay not have such a typedef (and in my test case, it doesn't). What I want to do, in C, is have a typedef that is PAYLOAD::key_type if IS_OUTER is true and just plain PAYLOAD if IS_OUTER is false. I cannot make it work. I've checked IS_OUTER and it has the correct value. But no matter what combination of if_c, eval_if_c, apply, etc. I use it won't compile because "'key_type' : is not a member of". Here's my basic example without the elaboration: typedef typename boost::mpl::if_c
::type testing;
That can't work. All the template arguments to boost::mpl::if_c must be
syntactically valid after substiution of C's template parameters, and
clearly that won't be the case. I think you need to write your own
selection template:
template
Ben Hutchings
Alan M. Carroll wrote:
typedef typename boost::mpl::if_c
::type testing; That can't work. All the template arguments to boost::mpl::if_c must be syntactically valid after substiution of C's template parameters, and clearly that won't be the case. I think you need to write your own selection template:
template
struct type_or_key_type { typedef T type; }; template<typename T> struct type_or_key_type { typedef typename T::key_type type; }; then use
typedef typename type_or_key_type
::type testing;
I'd normally solve it this way: template <class T> struct key_type { typedef typename T::key_type type; }; typedef mpl::eval_if_c< IS_OUTER , key_type<PAYLOAD> , mpl::identity<PAYLOAD> >::type testing; HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (4)
-
Alan M. Carroll
-
Ben Hutchings
-
David Abrahams
-
JOAQUIN LOPEZ MU?Z