Like boost::enable_if, but takes a "priority number" and changes overload resolution order

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Like boost::enable_if, but takes a "priority number" and changes overload resolution order

Dennis Ferron
>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.

Any comments or ideas for improving this?
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Like boost::enable_if but takes a "priority number" and changes overload resolution order

Steven Watanabe-4
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

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost