This is a simple question; suppose you have a template like this: template < unsigned long x > struct static_log2 { BOOST_STATIC_CONSTANT( int, value = ...); };
and that the implementation you use is absolutely general as far as the argument type is concerned; in other words: if C++0x will make unsigned long long available you want to replace unsigned long with that wider type. Specifically, this is the case for the excellent static_log2 implementation suggested by Vesa Karvonen a while ago on this list. A first, obvious, way to do this is to typedef the argument type: namespace boost { typedef unsigned long static_log2_argument_type; template < static_log2_argument_type x> struct static_log2 { ... } } 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'. 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? 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 = ...; }; Since log2<0> gives an error anyway, this would change nothing for the normal usage of computing a logarithm (i.e.: he should specify the argument anyway, as it is now). But, with that default, you could have: template <> struct argument_type< static_log2<> > { typedef static_log2_argument_type type; }; // usage: argument_type < static_log2<> > :: type However I don't like too much the idea to have a default argument (zero) which is a non-sense for the main usage of the template (calculating an algorithm) and whose only purpose is to use a simpler template-id in conjunction with argument_type<>. Also this is quite an ad-hoc approach, not suitable for other "unary compile-time-function templates" for which no "unusable default" exists. In short: I don't know what to do :-) Maybe we should simply have the convention that such templates provide typedefs with standard names, like argument_type and result_type? Thoughts? Genny. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost