Boost logo

Boost Users :

From: David Abrahams (dave_at_[hidden])
Date: 2007-10-16 16:52:41


on Tue Oct 16 2007, "Peng Yu" <pengyu.ut-AT-gmail.com> wrote:

> On 10/16/07, David Abrahams <dave_at_[hidden]> wrote:
>>
>> on Sat Oct 13 2007, "Peng Yu" <pengyu.ut-AT-gmail.com> wrote:
>>
>> > On 10/13/07, John Maddock <john_at_[hidden]> wrote:
>> >> Peng Yu wrote:
>> >> > Hi,
>> >> >
>> >> > Suppose I define a class fixed_point as
>> >> >
>> >> > class fixed_point{
>> >> > ....some operations are defined here
>> >> >
>> >> > private:
>> >> > int _integer_part;
>> >> > unsigned _fractional_part
>> >> > }
>> >> >
>> >> > I want is_arithmetic<fixed_point>::type to be true_
>> >>
>> >> The aim of is_arithmetic is that it returns true only for built-in
>> >> arithmetic types: in other words it's a type introspection tool. If you
>> >> specialise it for UDT's you will very likely break other code (for example
>> >> has_trivial_XXX assumes that all arithmetic types have trivial
>> >> construct/asign/copy/destroy operations). Probably the correct traits to be
>> >> specialising (and using to detect "numbers") is std::numeric_limits.
>> >
>> > Unfortunately, there are not types that contain constants in
>> > std::numeric_limits as in the boost type_traits library. If I want do
>> > metaprogramming based the types, I can not used numeric_limits. You
>> > have a point that specialize is_arithmetic might break other code. But
>> > are there any other walk around for this problem of adding user
>> > defined types?
>>
>> Yes.
>>
>> template <class T>
>> struct my_is_arithmetic : boost::is_arithmetic<T> {};
>>
>> now use my_is_arithmetic and specialize it for fixed_point.
>
> I assume that you suggest me to use my_is_arithmetic in the library
> class. However, my question was that I do not have the freedom to
> change the library (as discussed in the later message in this thread,
> dated Oct 16, 2007 11:20 AM). The following code shows the fact.
>
> #include <boost/type_traits.hpp>
> #include <iostream>
>
> struct fixed_point {
> };
>
> template <typename T>
> struct my_is_arithmetic : public boost::is_arithmetic<T> {
> };
>
> template <>
> struct my_is_arithmetic<fixed_point> : public boost::is_arithmetic<int> {
> };
>
> template <typename T>
> struct library_class_which_I_can_not_change {
> void doit() const {
> std::cout << boost::is_arithmetic<T>::type::value << std::endl;
> }
> };
>
> int main() {
> library_class_which_I_can_not_change<int>().doit();
> library_class_which_I_can_not_change<fixed_point>().doit();
> }
>
> /* output
> 1
> 0
> */

Then should implement a new class that uses my_is_arithmetic in terms
of the library_class_which_I_can_not_change. If you can't do that, I
think there are no good answers, so use whatever hack gets the job
done. :-)

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net