Strongly type doubles?

Discussion in 'C++' started by Joseph Turian, Nov 26, 2006.

  1. I want to create several types of double, e.g. D1 and D2.
    I want strong typing, such that a function defined for D1 will not
    accept a D2 argument.

    One solution is:
    struct D1 {
    double d;
    };

    However, the usage is cumbersome (I have to access member variable d),
    I don't have any operators defined, and object creation is more
    expensive than for native types (right?).

    Can someone propose an alternate solution that enforces the type safety
    I require?

    Thanks,

    Joseph
     
    Joseph Turian, Nov 26, 2006
    #1
    1. Advertising

  2. Joseph Turian wrote:
    > I want to create several types of double, e.g. D1 and D2.
    > I want strong typing, such that a function defined for D1 will not
    > accept a D2 argument.
    >
    > One solution is:
    > struct D1 {
    > double d;
    > };
    >
    > However, the usage is cumbersome (I have to access member variable d),
    > I don't have any operators defined, and object creation is more
    > expensive than for native types (right?).
    >
    > Can someone propose an alternate solution that enforces the type safety
    > I require?
    >
    > Thanks,
    >
    > Joseph


    If you use the structs, you could define conversion operators for D1
    and D2:

    struct D1 {
    double d;
    operator double () { return d; }
    };

    Then you will be able to use them in mathematical expressions because
    the conversion to double will take place automatically:

    D1 a, b;
    a.d = 15;
    b.d = 25;

    double c = a * b;

    You will also be able to have functions that accept D1 objects, but not
    raw doubles or D2 objects.

    If I'm not mistaken, the compiler should also inline the conversions,
    so you will not have any performance penalty for using them, instead of
    regular doubles.

    Regards,
    Markus.
     
    Markus Svilans, Nov 26, 2006
    #2
    1. Advertising

  3. Joseph Turian

    kwikius Guest

    Joseph Turian wrote:
    > I want to create several types of double, e.g. D1 and D2.
    > I want strong typing, such that a function defined for D1 will not
    > accept a D2 argument.
    >
    > One solution is:
    > struct D1 {
    > double d;
    > };
    >
    > However, the usage is cumbersome (I have to access member variable d),
    > I don't have any operators defined, and object creation is more
    > expensive than for native types (right?).
    >
    > Can someone propose an alternate solution that enforces the type safety
    > I require?


    It is perfectly possible to make your own types that act like doubles,
    but with whatever semantics you want to design in. Its not trivial
    though to get all the details the way you want them to be.

    The link here is to my code for a physical quantity type, but the
    underlying principle involved is the same for a strongly typed double:

    http://quan.sourceforge.net/index.html.

    For variables the assembly code is indistinguishable from that using
    doubles in most cases (using VC8.0 with a very good optimiser), however
    the code for literal constants is better optimised for inbuilt types so
    you do seem to lose performance there.

    regards
    Andy Little
     
    kwikius, Nov 26, 2006
    #3
  4. Markus Svilans:

    > If you use the structs, you could define conversion operators for D1
    > and D2:
    >
    > struct D1 {
    > double d;
    > operator double () { return d; }
    > };
    >
    > Then you will be able to use them in mathematical expressions because
    > the conversion to double will take place automatically:
    >
    > D1 a, b;
    > a.d = 15;
    > b.d = 25;
    >
    > double c = a * b;
    >
    > You will also be able to have functions that accept D1 objects, but not
    > raw doubles or D2 objects.


    Or something like:

    template<class T>
    struct TypeProcurer {
    typedef T Type;
    };

    #define DEFINE_LOAN_TYPE(name,T) \
    struct name { \
    typedef TypeProcurer< T >::Type Type; \
    Type obj; \
    name () {} \
    name (Type const &x) : obj(x) {} \
    operator Type&() { return obj; } \
    operator Type const&() const { return obj; } \
    };

    DEFINE_LOAN_TYPE(Double1,double)
    DEFINE_LOAN_TYPE(Double2,double)

    int main()
    {
    Double1 a = 5, b;

    b = a;
    a = b;
    a = b / 4;
    b *= a;

    Double2 c, d = 7;

    a = d; /* Compiler ERROR */
    }

    I would have used templates but I think the macro solution is cleaner. The
    DEFINE_LOAN_TYPE macro won't work with types which have a comma in them,
    but this can be remedied by using Variable Argument List macros (which are
    a part of C99).

    --

    Frederick Gotham
     
    Frederick Gotham, Nov 26, 2006
    #4
  5. Joseph Turian

    Greg Guest

    Frederick Gotham wrote:
    > Markus Svilans:
    >
    > > If you use the structs, you could define conversion operators for D1
    > > and D2:
    > >
    > > struct D1 {
    > > double d;
    > > operator double () { return d; }
    > > };
    > >
    > > Then you will be able to use them in mathematical expressions because
    > > the conversion to double will take place automatically:
    > >
    > > D1 a, b;
    > > a.d = 15;
    > > b.d = 25;
    > >
    > > double c = a * b;
    > >
    > > You will also be able to have functions that accept D1 objects, but not
    > > raw doubles or D2 objects.

    >
    > Or something like:
    >
    > template<class T>
    > struct TypeProcurer {
    > typedef T Type;
    > };
    >
    > #define DEFINE_LOAN_TYPE(name,T) \
    > struct name { \
    > typedef TypeProcurer< T >::Type Type; \
    > Type obj; \
    > name () {} \
    > name (Type const &x) : obj(x) {} \
    > operator Type&() { return obj; } \
    > operator Type const&() const { return obj; } \
    > };
    >
    > DEFINE_LOAN_TYPE(Double1,double)
    > DEFINE_LOAN_TYPE(Double2,double)
    >
    >
    > I would have used templates but I think the macro solution is cleaner. The
    > DEFINE_LOAN_TYPE macro won't work with types which have a comma in them,
    > but this can be remedied by using Variable Argument List macros (which are
    > a part of C99).


    The boost "strong typedef" also uses both a macro and templates:

    #include <boost/operators.hpp>

    #define BOOST_STRONG_TYPEDEF(T, D) \
    struct D \
    : boost::totally_ordered1< D \
    , boost::totally_ordered2< D, T \
    > > \

    { \
    T t; \
    explicit D(const T t_) : t(t_) {}; \
    D(){}; \
    D(const D & t_) : t(t_.t){} \
    D & operator=(const D & rhs) { t = rhs.t; return *this;} \
    D & operator=(const T & rhs) { t = rhs; return *this;} \
    operator const T & () const {return t; } \
    operator T & () { return t; } \
    bool operator==(const D & rhs) const { return t == rhs.t; } \
    bool operator<(const D & rhs) const { return t < rhs.t; } \
    };

    Greg
     
    Greg, Nov 27, 2006
    #5
  6. Joseph Turian

    Guest

    Joseph Turian wrote:
    > I want to create several types of double, e.g. D1 and D2.
    > I want strong typing, such that a function defined for D1 will not
    > accept a D2 argument.
    >
    > One solution is:
    > struct D1 {
    > double d;
    > };
    >
    > However, the usage is cumbersome (I have to access member variable d),
    > I don't have any operators defined, and object creation is more
    > expensive than for native types (right?).
    >
    > Can someone propose an alternate solution that enforces the type safety
    > I require?


    Using double type to represent mass and velocity can be expressed as
    Dimensional Analysis.

    Using the compiler to enforce strongly typed doubles is discussed by
    following the link below.

    http://www.nwcpp.org/Meetings/2005/09.html

    You will find a link to a pdf with the lecture notes.

    --
     
    , Nov 30, 2006
    #6
  7. Joseph Turian

    Noah Roberts Guest

    wrote:

    > Using double type to represent mass and velocity can be expressed as
    > Dimensional Analysis.


    Yes, much can be done if you know what the problem domain is. The OP
    wasn't very specific though so the answers they are going to get are
    going to be the best they can be but probably not that useful.
     
    Noah Roberts, Nov 30, 2006
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kloofy
    Replies:
    0
    Views:
    329
    Kloofy
    Jul 8, 2005
  2. dan
    Replies:
    1
    Views:
    2,365
    Jack Klein
    Nov 26, 2003
  3. Chris

    Strongly Type Datasets

    Chris, May 27, 2007, in forum: ASP .Net
    Replies:
    5
    Views:
    370
  4. Victor Bazarov
    Replies:
    6
    Views:
    350
    Bo Persson
    Aug 18, 2011
  5. Replies:
    36
    Views:
    949
    Alexey Verkhovsky
    Feb 26, 2008
Loading...

Share This Page