On Sun, 02 Feb 2003 08:35:56 -0500, David Abrahams
<[EMAIL PROTECTED]> wrote:

>> This of course works, but the typedef name is quite "log specific";
>> certainly that's worse than having a generic name available at class
>> scope:
>>
>>
>>    template <...>
>>    struct static_log2 {
>>      typedef ... argument_type;    // (*)
>>    };
>>
>>
>> As Terje Slettebų noticed in private mail, this is a general problem
>> for any 'compile-time function'. 
>
>("metafunction")

Well, the term 'compile-time function' was mine, so if it is an error
it is my fault, not Terje's. Maybe I'm not aligned to the standard
terminology, but to me the prefix meta- means "that refers to
something of its same nature", thus for instance a meta-sentence is a
sentence that talks about sentences, a metarule is a rule about rules
and a metaprogram is a program that generates a program. Since a class
template doesn't generate a function I don't call it a metafunction,
though of course if you intend 'function' in a wider meaning then you
can do that as well.


>> A similar issue, for the run-time counter-part, is solved by
>> std::unary_function and std::binary_function. What should we do for
>> the compile-time case?  
>
>I don't think the analogy is a good one.  unary_ and binary_function
>just supply the typedefs for /specific/ function argument types.
>
>The compile-time case should be handled by passing types instead of
>numbers.  If you need the other interface for convenience or legacy
>reasons you can always write static_log2_c<unsigned long>.
>
>Note that using types can allow you to compute a static log2 of
>extended long values even if the C++ compiler doesn't have them built
>in.  One just needs an appropriate wrapper type such as:
>
>     template <unsigned long hi, unsigned long lo>
>     struct long_long
>     {
>        typedef long_long type;
>        unsigned long hi_value;
>        unsigned long lo_value;
>     };
>
>and specializations of all of the arithmetic primitive metafunctions
>you'll need to use to operate on it.

Yes, but it's quite overkilling in this case. At a point, you have to
balance the generality with the complexity cost (not to talk, in this
case, about compile times).

>> Note that to use argument_type in the above (*) you have to specify
>> an argument for static_log2, despite the fact that actually the
>> typedef doesn't depend on the value of which you compute the
>> logarithm. Even if you introduce, say, an argument_type<> template,
>> like this:
>>
>>    // specialize this as needed
>>    template <typename T> struct argument_type;
>>
>>    template <static_log2_argument_type x>
>>    struct argument_type< log<x> > {
>>      typedef static_log2_argument_type type;
>>    };
>>
>> you still don't solve the problem of the dummy argument: e.g.
>>
>>    argument_type< log<1> > :: type;  // why 1?
>>
>> Unfortunately you can't default x to zero in the argument_type
>> specialization above. In fact, in this specific case, you could resort
>> to:
>>
>>    template <static_log2_argument_type x = 0> 
>>    struct log { 
>>      static const int value = ...; 
>>    };
>>
>
>You've completely lost me here.  I tried to understand it three times,
>and gave up.

Sorry, I should have been clearer. The idea was to use a non-intrusive
way to gather the argument type of a generic unary 'metafunction'. The
template argument_type<>, to be specialized as needed, provided a
uniform interface for that; for instance:

   template <typename T>
   struct argument_type;

   template <>
   struct argument_type<MyMetaFunction> {
     typedef ... type;
   };

For static_log2 you would specialize it as:

   template < unsigned long x > 
   struct argument_type< static_log2<x> > { 
     typedef unsigned long type;

   };


That, however, still requires you to specify a number (whatever it is)
when requiring the argument type:

  argument_type < static_log2<16> > :: type

whereas I think the intuitive syntax would be:

  argument_type < static_log2<> > :: type

To get the intuitive syntax, you can't use a default value in the
specialization of argument_type, simply because that's illegal. But
you could, if you really strive for it at all costs, use a default
(=0) for static_log2 itself. How ugly (and ad-hoc) that would be is
evident to everyone, so I was just, to say, thinking out loud in the
hope that it could suggest other ideas.


Genny.

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

Reply via email to