|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2003-01-11 22:02:15
"Paul Mensonides" <pmenso57_at_[hidden]> writes:
> ----- Original Message -----
> From: "David Abrahams" <dave_at_[hidden]>
>
>> > solution:
>> >
>> > There is no non-intrusive solution. It must be cast at the call site to
> a
>> > common type (such as 'int' or 'bool') in order to avoid replicated
> template
>> > instantiation.
>> >
>> > ---- */
>>
>> Of course, you can use the first solution with enums as well:
>>
>> template <class T, T N>
>> struct integral_c
>> {
>> enum value_type { value = N; };
>> };
>>
>> template<class T> struct Y
>> : integral_c<int,10> {};
>>
>>
>> Now Y<int>::value and Y<double>::value have the same type. Of course,
>> you will probably want some additional tools in integral_c<T,N>, like
>> an explicit conversion to an rvalue of type T.
^^^^^^^^
> Well, yes. If you do that, however, it removes one of the primary reasons
> to use enumerations, which is for the syntactic convenience. The only
> reason left to use enums is to avoid the static storage of the
> values.
And to improve compilation and linking speed.
> The automatic rvalue conversion would be nice, but you'd still get
> the template instantiation problem if you did this:
>
> template<class T> void f(const T&);
>
> template<class T> class is_integer : integral_c<bool, false> { };
> template<> class is_integer<int> : integral_c<bool, true> { };
>
> template<class T> void f(const T&);
>
> int main() {
> f( is_integer<int>() ); // 'T' == 'is_integer<int>'
> return 0;
> }
Not if the conversion were explicit:
f( is_integer<int>::get() );
> What you need is both 'value' and 'rvalue':
>
> template<class T, T V> struct integral_c {
> enum value_type { value = V };
> static inline T rvalue() {
> return value;
> }
> };
>
> int main() {
> f( is_integer<int>::rvalue() ); // better
> return 0;
> }
That's what I meant all along. I like your name, 'rvalue'.
> This still doesn't solve one other issue though:
>
> template<class T> T operator && (T, T); // etc.
>
> ...which is evil, I agree, but possible. This can still break any
> arithmetic or logical operations that involve enumerations:
>
> is_integer<int>::value && is_integer<int>::value // not constant
>
> The only solution that I see is:
>
> (bool)is_integer<int>::value && (bool)is_integer<int>::value
Pshaw. "Doctor, it hurts when I do this"
so-don't-do-it-ly y'rs,
dave
-- David Abrahams dave_at_[hidden] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk