|
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_<
boost::is_scalar<T>,
typename boost::mpl::if_<
boost::is_enum<T>, tag_enum, tag_scalar
>::type, tag_other
>::type type;
};
template<typename T> struct M_impl;
template<>
struct M_impl<tag_other> {
static void foo() { std::cout << "generic" << std::endl; }
};
template<>
struct M_impl<tag_scalar> {
static void foo() { std::cout << "scalar" << std::endl; }
};
template<>
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()
{
M<S>::foo();
M<int>::foo();
M<FOO>::foo();
}
-- Stirling Westrup Programmer, Entrepreneur. https://www.linkedin.com/e/fpf/77228 http://www.linkedin.com/in/swestrup http://technaut.livejournal.com http://sourceforge.net/users/stirlingwestrup
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