Boost logo

Boost :

Subject: Re: [boost] Like boost::enable_if but takes a "priority number" and changes overload resolution order
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2010-05-09 09:54:23


AMDG

Dennis Ferron wrote:
> >From the Boost documentation: "The enable_if family of templates is a set
> of tools to allow a function template or a class template specialization to
> include or exclude itself from a set of matching functions or
> specializations based on properties of its template arguments."
>
> Sometimes instead of completely excluding a function from overload
> resolution, I only really want to "tweak" C++'s overload resolution order,
> or disambiguate an edge case. Instead of relying on C++'s overload
> priorities, sometimes I'd like to explicitly set the overload priority, like
> this:
>
> template <typename T>
> void func(boost::overload_priority<1> dummy, ArgType1 arg) {}
>
> template <typename T>
> void func(boost::overload_priority<2> dummy, ArgType2 arg) {}
>
> template <typename T>
> void func(boost::overload_priority<3> dummy, ArgType3 arg) {}
>
> Whereas enable_if causes a "hard" error to trigger SFINAE and take a
> function out of consideration, overload_priority would have some sort of
> "soft" effect that "tricks" the C++ compiler into thinking it is a less
> specific match than it is, moving it down in the order of which gets chosen,
> without actually invalidating it. It isn't obvious that this is even
> possible, but then, I would never have believed "enable_if" was possible
> before I heard of it. Whereas enable_if works by wrapping the return type
> of the function, I believe this would have to wrap a function argument to
> work. What I have in mind is that the overload_priority class would look
> like this:
>
> template <int N>
> class overload_priority
> {
> public:
> overload_priority(int x) { ... }
> };
>
> You would call the overloaded function like this:
>
> func(0, the_actual_arg);
>
> I'm thinking it would affect the overload priority by some trick like
> causing an N-deep nested conversion sequence (overload_priority<3>
> constructed from overload_priority<2>, from overload_priority<1>, from the
> integer 0) or by the constructor having N extra parameters with default
> arguments.
>

C++ only allows a single user defined conversion in a
conversion sequence. You'd have to use many levels
of inheritance.

template<int N>
struct overload_priority : overload_priority<N+1> {};

// base case
template<>
struct overload_priority<16> {};

func((overload_priority<0>*)0, ...);

> Any comments or ideas for improving this?
>

In Christ,
Steven Watanabe


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk