|
Boost : |
Subject: Re: [boost] New, powerful way to use enable_if in C++0x
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2011-04-12 10:10:50
On Tue, Apr 12, 2011 at 6:00 AM, Stewart, Robert <Robert.Stewart_at_[hidden]>wrote:
> Krzysztof Czainski wrote:
> > 2011/4/12 Stewart, Robert <Robert.Stewart_at_[hidden]>
> > > >
> > > I wonder if you couldn't repackage your idea in, say,
> > > enable_when and disable_when (plus variants) so that the
> > > usage is slightly simpler:
> > >
> > > class test
> > > {
> > > template
> > > <
> > > class... T
> > > , typename boost::enable_when_c<sizeof...(T) == 10>::type = true
> > > >
> > > test(T &&...);
> > > };
> > >
> > > IOW, enable_when_c would expose a nested type, type, of
> > > type bool that makes forming the default easy[*]. You could
> > > use a pointer or integer type and default to 0, for example,
> > > but expressing the default as "= true" just looks good and
> > > is easy to remember.
> > >
> > Enable_when looks good to me, except for one detail:
> > "enable_when< [...] >::type = true" may confuse someone, that
> > "enable_when< [...] >::type = false" is a synonym for
> > "disable_when< [...] >::type = true", so I'm be against the
> > part "= true". I'd most like it to be "= 0", but
> > "= boost::enabler" looks ok to me too.
>
> I thought about the "= false" issue, but not from the perspective of
> someone thinking it would negate the logic. We can document that the
> convention is to use "= true", but that "= false" has the same effect but
> with less clarity. I really doubt anyone would choose "= false" unless they
> thought it would negate the logic. Still, I think documentation can prevent
> that misuse by virtue of a stern warning.
>
> "= 0" would also work, if the type is a pointer or integer type, but other
> pointer or integer values can then be used, so they really aren't different
> than true/false. (Actually, "= 0" would work if the type were bool, too.)
> Non-zero values might be thought of as normal, and zero values as negated,
> logic, thus leading to the same concerns as for bool.
>
> I don't care for boost::enabler because "boost::" and "enable" are repeated
> (the first "enable" is in "enable_when") and a long line is made even
> longer. Note that the use of boost::enabler is optional: the type is void
> *&, so, for example, "= 0" works just as well and might be thought to negate
> enable_when.
>
> If enable_when/disable_when were to use a pointer to a UDT and
> boost::enabler were a pointer of that type, then that might be the only
> convenient value aside from zero, but that doesn't avoid the possible
> confusion as with each of the other options.
>
> The only ways I can think of to force one default value is with an
> enumerated type or a UDT with a member the address of which must be
> supplied. The latter requires that the member have external linkage, so the
> former is simpler:
>
> namespace boost
> {
> enum enabler { is_true }; // some clear, short, non-clashing name
> }
>
> boost::enable_when<...>::type = boost::is_true
>
> That would use enable_if<...,enabler>::type, of course.
>
Ease-of-use and conciseness are certainly concerns, but might I suggest:
don't add anything yet to the Boost.EnableIf library, just update the
documentation to mention the use of Boost.EnableIf in defaulted template
parameters (perhaps in all the different styles mentioned above), and see if
anything close to idiomatic settles in. Unless, I guess, there's broad
consensus on the list regarding a particular style...
- Jeff
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk