Boost logo

Boost Users :

Subject: Re: [Boost-users] enable-if overloading out the wazoo
From: Jeremiah Willcock (jewillco_at_[hidden])
Date: 2010-04-23 17:35:54


On Fri, 23 Apr 2010, John Dlugosz wrote:

> I tried something like this: First, the general form in one header known by everything:
>
> template <typename T1, typename T2>
> dim_s foo (const T1& left, const T2& right);
>
> Then, in a header that gets more concrete, provide its own form that is
> meant to be used when objects of those types are involved:
>
> template<typename T1, typename T2>
> typename enable_if_c<
> is_base_of<genericbase,T1>::value &&
> is_base_of<genericbase,T2>::value,
> dim_s>::type foo (const T1& left, const T2& right);
>
> Here, the template defined in this header derives from genericbase, so I
> have a hook to say "all types derived from any specialization of this
> template".
>
> Now, this actually causes an ambiguity. The latter is not a
> specialization but a peer overloading, and when both are present, both
> are templates that form exact matches and template arguments at the
> least restrictive way to refer to the type.
>
> This function is already internal plumbing, so I don't mind it being a
> little messy to use. What I'm really doing is multimethod dispatch:
> various concrete classes, generic versions for making such, and special
> combinations all have their own efficient logic, with a fallback (slow)
> that always works. And I want all the plumbing to disappear at compile
> time so it efficiently calls the efficient function. So if I'm really
> guilty of the "X for Y" problem, that is what I'm really trying to do,
> and if there are any suggestions on doing that better in general, please
> let'em rip.

Have you seen <URL:http://www.codeproject.com/KB/recipes/mmcppfcs.aspx>?

> As for the road I'm on now, the simplest thing is to somehow give each
> form a priority. I did that by adding a 3rd parameter. The general
> form declares a void*, and the specialized form declares an int. The
> caller always gives a zero. I'm wondering what is the longest chain of
> different priorities I can use with this method, using only compiler
> primitive types that the optimizer should be able to toss when the
> function is inlined. I know I could use dummy classes with any number
> of derivations, but I'm thinking I can get several levels just using
> primitive types. Any suggestions?

What about (... is for you to fill in):

template <..., typename X> // Priority 0
void foo(..., X);

template <..., typename X> // Priority 1
void foo(..., X*);

template <..., typename X> // Priority 2
void foo(..., X**);

Then call foo(..., (void*******************)0) (for however many priority
levels you want to allow). Perhaps you can even use a default argument to
fill in the value in C++0x, but I'm not sure about that. You can of
course write a wrapper function that adds in the dummy last argument.

-- Jeremiah Willcock


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