Boost logo

Boost Users :

Subject: Re: [Boost-users] enable_if and multiple partial specializations
From: Stirling Westrup (swestrup_at_[hidden])
Date: 2011-04-08 13:12:59

On Fri, Apr 8, 2011 at 11:04 AM, Joel Falcou <joel.falcou_at_[hidden]> wrote:
> On 08/04/11 17:05, Gennadiy Rozental wrote:
>> This will not really work for me. This was just an artificial example. In
>> reality I have generic header which defines the template, another common
>> header which defines some not very specific specialization and multiple (number
>> changes as project grows) headers where I define more specific specializations. I
>> can't "NOT" all the specific conditions in "scalar" level specialization - It's
>> just not maintainable.
>> Any other options?
> - have a first level function enable_if on the highest catching metafunction
> then do tag dispatching inside to other function enabled_if on
> specialization of said initial test.
> - build sensible, non overlapping traits for your cases and use these
> instead of raw type traits.
> enable_if cant work with overlapping conditions.

This suggestion really is your best bet. To elaborate a bit further,
you don't really even want to use enable_if in this case. You really
want to write something like:

#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_scalar.hpp>

#include <iostream>

struct tag_other{};
struct tag_scalar{};
struct tag_enum : tag_scalar{};

// there are many better ways of writing tag_lookup.
// This is just an example.
template<typename T>
struct tag_lookup {
  typedef typename boost::mpl::if_<
      typename boost::mpl::if_<
        boost::is_enum<T>, tag_enum, tag_scalar
>::type, tag_other
>::type type;

template<typename T> struct M_impl;

struct M_impl<tag_other> {
   static void foo() { std::cout << "generic" << std::endl; }

struct M_impl<tag_scalar> {
   static void foo() { std::cout << "scalar" << std::endl; }

struct M_impl<tag_enum> {
   static void foo() { std::cout << "enum" << std::endl; }

template<typename T>
struct M : M_impl< typename tag_lookup<T>::type >

struct S {};
enum FOO { FOO1, FOO2 };

int main()

Stirling Westrup
Programmer, Entrepreneur.

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at