Strongly type doubles?

J

Joseph Turian

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
 
M

Markus Svilans

Joseph said:
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.
 
K

kwikius

Joseph said:
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
 
F

Frederick Gotham

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).
 
G

Greg

Frederick said:
Markus Svilans:


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
 
A

artpanneknwcpp

Joseph said:
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.

--
 
N

Noah Roberts

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top