
From: "Alex Chovanec" <chovanec@llnl.gov>
Terje Slettebø <tslettebo@broadpark.no> writes:
The current version of is_xxxable.hpp in Yahoo Files does seem to have some problems, when it comes to implicit conversions.
I discovered another problem with these macros after I uploaded them. The original 'is_dereferenceable' implementation relied upon special handling for fundamental types. The reason is that attempting to dereference something like an 'int' or 'float' is going to cause a compiler error no matter what, even if there is a last resort 'operator*'. To solve this problem, I rigged 'is_dereferenceable' to return false for all fundamental types. (Pointers are not considered fundamental types.) This special handling was carried over into the 'is_xxxable' macros, and it doesn't generalize to other operators. For instance, if I use 'BOOST_IS_XXXABLE_PREFIX' to generate 'is_incrementable', I get a metafunction that returns 'false' for integers.
Of course, this problem can be fixed, but probably not without some special handling for specific fundamental types and/or operators, which kind of defeats the purpose of having a generalized macro.
Exactly. If you look at the implementation of the traits in the library I uploaded, e.g. has_plus_op, you'll see that it has a two-part implementation: The first part "filters" the types (using type traits and MPL's logical metafunctions, not specialisations), and it ends with "detail::has_plus_op_impl<T,U>". Only if it passes the first part, will it attempt this final check, where it tries to perform T1 + T2 (with the ...-overload if there's no existing operator+ for them). The first filtering ensures that - as you say about dereferencing the fundamental types - it doesn't try to do e.g. void + void, because that will fail with an error, regardless of the ...-overload (overloaded functions are not considered for built-in types). On the surface, it may seem logical that it should be possible to write a "generic macro" for all operators, but when you get down to actually doing it, and testing it against all kinds of types, you find that you need this "pre-filtering" phase to avoid errors, and as you also point out, that phase is different for different operators. It's not as "easy" as it may seem. Regards, Terje