Gennaro Prota <[EMAIL PROTECTED]> writes:

> --- David Abrahams <[EMAIL PROTECTED]> wrote:
>
>> You can do that, but IIUC it won't get you where Genny's trying to go:
>> namely that if static_log2 happens to get adjusted so its parameter is
>> an unsigned long long constant, you can detect that without causing an
>> error.
>
> No. Because in the real code I would have written:
>
>   // actually in namespace detail
>   typedef unsigned long static_log2_arg_type; // (*)
>
>
>   template <static_log2_arg_type N>
>   struct static_log2 {};
>
>   template <class T>
>   struct argument_type;
>
>   template < static_log2_arg_type x > // ***
>   struct argument_type< static_log2<x> > {
>      typedef static_log2_arg_type type;
>   };
>
> and the only point subject to modification would have been (*). My problem was
> just that I don't like to specify a value when retrieving the argument type.

Yes, I can understand that.  

Let me see if I can make my point clearly.  


First, why would you ever use argument_type< ... > instead of simply
writing static_log2_arg_type?  If you knew you were operating on
static_log2, argument_type doesn't buy you anything.  You would only
use argument_type in some kind of generic higher-order metafunction
which, conceptually, is parameterized on another metafunction (that
could turn out to static_log2).  OK so far?

Now, consider the limitations on how that higher-order metafunction
can be written.  The most naive way to pass a metafunction is to use a
template template parameter:

    template <template <unsigned long> class F>
    struct higher_order_func
    {
        ...
        typedef typename argument_type<F<N> >::type arg_type;
        ...
    };

Well, that doesn't work for lots of reasons.  First, the signature of
higher_order_func already restricts F to be parameterized on unsigned
long.  Second, you have to come up with an appropriate value of N.

So what are your alternatives?  You can ask the user to deliver a type
argument to higher_order_func instead, like static_log2<0>, but you're
just passing the buck: the user has to know that zero is a magical
value.  OK, so the best choice you have left is to ask the user to
pass static_log2<>.  But then, most numerical functions don't have a
magical invalid value that they can use as a default.  It's no problem
for types (witness MPL's placeholders), but not for numbers.  And do
you really want to establish required defaults as part of your
metafunction protocol?  That could make it a lot harder to find arity
errors at compile-time.

My point is this: the only thing that would make argument_type
worthwhile, i.e. the ability to do higher-order functional
programming, really requires that metafunctions have a consistent
polymorphic interface (i.e. type arguments and results).  So if you
really insist that static_log2 will not take a type argument, that's
fine, but don't waste your time trying to get argument_type to work.

You're not operating in a generic world, because there's no way to
generalize the neccessary default argument to arbitrary metafunctions
with that form.  You might as well settle for static_log2_arg_type
instead.

-- 
                       David Abrahams
   [EMAIL PROTECTED] * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution

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

Reply via email to