Topic: newtype
Author: kon@iki.fi (Kalle Olavi Niemitalo)
Date: Tue, 27 Jan 2004 17:35:15 +0000 (UTC) Raw View
rdsbrows@nospam.onet.pl ("Rafal Dabrowa") writes:
> Additionally, we are not able to create a template like:
> template <class T> class new_type { /* ... */ }
> used like this:
> typedef new_type<int> MONEY_T;
> typedef new_type<int> WEIGHT_T;
> This class wouldn't behave as expected: both types are
> synonyms for new_type<int> and can be used
> interchangeably.
You could perhaps add a dummy parameter to the template.
The template would not actually use the parameter, but
different arguments would result in different types.
template <class T, class tag> class new_type { /* ... */ };
struct money_tag {};
typedef new_type<int, money_tag> MONEY_T;
struct weight_tag {};
typedef new_type<int, weight_tag> WEIGHT_T;
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bekkah@web.de (Helium)
Date: Tue, 3 Feb 2004 21:25:24 +0000 (UTC) Raw View
> Ada has a possibility to derive a new type from an existing one.
> Derived type behaves like original, but, unlike a type defined by typedef,
> can't be used interchangeably with another derived types (unless
> explicitly casted). Why C++ does not have such possibility ?
> Suppose that we define such types like typedef, using "newtype" keyword:
> newtype int MONEY_T;
> newtype int WEIGHT_T;
>
> void use_money(MONEY_T) { /* ... */ }
> MONEY_T money;
> WEIGHT_T weight;
>
> use_money(money); // OK
> use_money(1234); // OK
> use_money(weight); // oops! compilation error
> use_money( static_cast<MONEY_T>(weight) ); // OK
>
> I think that such construction would allow to catch a bit more
> errors at compilation time.
> Althrough we can create a class MONEY_T and
> WEIGHT_T, but why create a new, complicated class
> for state like "this is an int, but it keeps money only" ?
> Nobody does that. Instead, we are using often:
> typedef int MONEY_T;
> typedef int WEIGHT_T;
> and we think "this is a money" and "this is a weight".
> But compiler does not know our intentions - any mistake
> it compiles without problems.
> Additionally, we are not able to create a template like:
> template <class T> class new_type { /* ... */ }
> used like this:
> typedef new_type<int> MONEY_T;
> typedef new_type<int> WEIGHT_T;
> This class wouldn't behave as expected: both types are
> synonyms for new_type<int> and can be used
> interchangeably.
>
But what happens, if I do the following
struct Foo {};
newtype Foo Bar {};
struct FooD : public Foo {};
struct BarD : public Bar {}; // allowed?
Bar * bar = new BarD; // allowed?
Foo * foo = new BarD; // allowed?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: v.Abazarov@comAcast.net ("Victor Bazarov")
Date: Tue, 3 Feb 2004 22:34:30 +0000 (UTC) Raw View
"Helium" <bekkah@web.de> wrote...
> > Ada has a possibility to derive a new type from an existing one.
> > Derived type behaves like original, but, unlike a type defined by
typedef,
> > can't be used interchangeably with another derived types (unless
> > explicitly casted). Why C++ does not have such possibility ?
> > Suppose that we define such types like typedef, using "newtype" keyword:
> > newtype int MONEY_T;
> > newtype int WEIGHT_T;
> >
> > void use_money(MONEY_T) { /* ... */ }
> > MONEY_T money;
> > WEIGHT_T weight;
> >
> > use_money(money); // OK
> > use_money(1234); // OK
> > use_money(weight); // oops! compilation error
> > use_money( static_cast<MONEY_T>(weight) ); // OK
> >
> > I think that such construction would allow to catch a bit more
> > errors at compilation time.
> > Althrough we can create a class MONEY_T and
> > WEIGHT_T, but why create a new, complicated class
> > for state like "this is an int, but it keeps money only" ?
> > Nobody does that. Instead, we are using often:
> > typedef int MONEY_T;
> > typedef int WEIGHT_T;
> > and we think "this is a money" and "this is a weight".
> > But compiler does not know our intentions - any mistake
> > it compiles without problems.
> > Additionally, we are not able to create a template like:
> > template <class T> class new_type { /* ... */ }
> > used like this:
> > typedef new_type<int> MONEY_T;
> > typedef new_type<int> WEIGHT_T;
> > This class wouldn't behave as expected: both types are
> > synonyms for new_type<int> and can be used
> > interchangeably.
> >
> But what happens, if I do the following
>
> struct Foo {};
> newtype Foo Bar {};
My guess is that you won't need the curly braces here. Just
newtype Foo Bar;
Now, Bar is a synonym of Foo in functional sense but cannot
be substituted for Foo where Foo is expected. That's what
happens.
>
> struct FooD : public Foo {};
> struct BarD : public Bar {}; // allowed?
Why not? 'Bar' is a complete type, a mirror, so to speak, of
Foo. If you can derive from Foo, you should be able to derive
from Bar.
>
> Bar * bar = new BarD; // allowed?
Sure. Pointer-to-Derived to Pointer-to-Base conversion.
> Foo * foo = new BarD; // allowed?
I wouldn't think so. Since Foo and Bar are not the same and
cannot be used in place of one another, there is no conversion
between a pointer to something derived from Bar into Foo.
Victor
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bekkah@web.de (Helium)
Date: Wed, 4 Feb 2004 15:29:50 +0000 (UTC) Raw View
> > But what happens, if I do the following
> >
> > struct Foo {};
> > newtype Foo Bar {};
>
> My guess is that you won't need the curly braces here. Just
>
> newtype Foo Bar;
>
> Now, Bar is a synonym of Foo in functional sense but cannot
> be substituted for Foo where Foo is expected. That's what
> happens.
Oops, of course. Of course I ment
newtype Foo Bar;
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: technews@kangaroologic.com ("Jonathan Turkanis")
Date: Sun, 25 Jan 2004 20:04:52 +0000 (UTC) Raw View
""Rafal Dabrowa"" <rdsbrows@nospam.onet.pl> wrote in message
news:buldfh$2u2$1@news.onet.pl...
>
> Ada has a possibility to derive a new type from an existing one.
> Derived type behaves like original, but, unlike a type defined by
typedef,
> can't be used interchangeably with another derived types (unless
> explicitly casted). Why C++ does not have such possibility ?
> Suppose that we define such types like typedef, using "newtype"
keyword:
> newtype int MONEY_T;
> newtype int WEIGHT_T;
>
You seem to be advocating "strong typedefs". This has been discussed
for C++, with the following syntax:
strong_typedef int money_t;
strong_typedef int weight_t;
See "Asepcts of Forwarding" by Lois Goldthwaite
(http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1395.txt).
Jonathan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: rdsbrows@nospam.onet.pl ("Rafal Dabrowa")
Date: Fri, 23 Jan 2004 23:19:06 +0000 (UTC) Raw View
Ada has a possibility to derive a new type from an existing one.
Derived type behaves like original, but, unlike a type defined by typedef,
can't be used interchangeably with another derived types (unless
explicitly casted). Why C++ does not have such possibility ?
Suppose that we define such types like typedef, using "newtype" keyword:
newtype int MONEY_T;
newtype int WEIGHT_T;
void use_money(MONEY_T) { /* ... */ }
MONEY_T money;
WEIGHT_T weight;
use_money(money); // OK
use_money(1234); // OK
use_money(weight); // oops! compilation error
use_money( static_cast<MONEY_T>(weight) ); // OK
I think that such construction would allow to catch a bit more
errors at compilation time.
Althrough we can create a class MONEY_T and
WEIGHT_T, but why create a new, complicated class
for state like "this is an int, but it keeps money only" ?
Nobody does that. Instead, we are using often:
typedef int MONEY_T;
typedef int WEIGHT_T;
and we think "this is a money" and "this is a weight".
But compiler does not know our intentions - any mistake
it compiles without problems.
Additionally, we are not able to create a template like:
template <class T> class new_type { /* ... */ }
used like this:
typedef new_type<int> MONEY_T;
typedef new_type<int> WEIGHT_T;
This class wouldn't behave as expected: both types are
synonyms for new_type<int> and can be used
interchangeably.
Rafal
--
sed -e s/s/a/g <my_address >my_right_address
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]