Boost logo

Boost :

From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2003-01-07 19:01:04


----- Original Message -----
From: "Gennaro Prota" <gennaro_prota_at_[hidden]>

[...]
>I like static const, as I think it conveys more succinctly what it's about,
>and the enum appears more like a hack (for compilers not handling static
>const in-class initialisation). However, if this means it may need an
>out-of-class definition, as well, perhaps this could need to be
>reconsidered?

I like the strong-typing implied by the use of static const, and therefore
the overload simplication if it is ever used in such a fashion. The
out-of-class definition is annoying, so I tend to do this:

template<class T, T V> struct map_integral {
    static const T value = V;
};

template<class T, T V> const T map_integral<T, V>::value;

...and then reuse it:

template<class T> struct is_ptr : map_integral<bool, false> { };
template<class T> struct is_ptr<T*> : map_integral<bool, true> { };

This removes the need to make the out-of-class definition unless more than
one value is present (which can be handled similarly). It also maps each
value to the same storage. So, for example, there are only two addresses
necessary for boolean values.

Furthermore, enumerations can have overloaded operators. Consider the case
of "x + y" where both are enumerators. By default, everything is fine
because you have int(x) + int(y). If a template operator+ just happens to
be defined though, suddenly a bunch of "constant expressions" are no longer
constant.

Actually, this seems to be a bug in Comeau C++:

#include <iostream>
#include <typeinfo>

struct A {
    enum type { x, y };
};

template<int> struct B { };

template<class T> inline T operator+(T lhs, T rhs) {
    throw 0;
}

int main() try {
    std::cout
        << typeid( B<A::x + A::y> ).name() << &std::endl
                       // ^
                       // Comeau C++ doesn't flag this,
                       // but I think it should.
                       // Am I wrong here?
        << A::x + A::y << &std::endl;
}
catch (int) {
    std::cout << "template operator used" << &std::endl;
    return 0;
}

Better yet, if you remove the name "type" from the enumeration (ala 'enum
{ x, y }') you'll get a compile-time error for attempting to use an unnamed
type as a template argument.

Just my 2 cents.

Paul Mensonides


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk