D - opCast
- Vathix (11/11) Jan 20 2004 Overloading an object to cast to another type:
- Georg Wrede (2/13) Jan 20 2004 This seems so natural that it shouldn't even be a question! :-)
- davepermen (5/22) Jan 20 2004 wich is the same as operator Type() in c++, wich should be used in as le...
- Matthew (5/31) Jan 21 2004 Wow! I hadn't looked at the example enough to realise that it was propos...
- davepermen (21/55) Jan 21 2004 i think if cast(Type) will switch over to a template syntax, a.k.a.
- Georg Wrede (5/31) Jan 21 2004 Ok, I don't know enough about this to argue.
- Burton Radons (14/17) Jan 21 2004 Implicit casting is all right /so long as/ you distinguish between
- davepermen (7/24) Jan 22 2004 i'm not sure. i don't really like it by default.
- Ilya Minkov (12/18) Jan 23 2004 I agree that we need something like that for symmetry. But to be used
- Matthew (10/27) Jan 23 2004 type opExplicitCast()
- Ilya Minkov (14/34) Jan 23 2004 It may not be appropriate in all cases. A shim requieres explicit
- Vathix (4/7) Jan 23 2004 I was going to suggest that first, but since you can't overload return
- Ilya Minkov (5/9) Jan 24 2004 Whoops! My fault. You are right. In my background, return values cannot
Overloading an object to cast to another type: class Another { char[] str; this(char[] init) { str = init; } void opCast(out char* result) { result = toStringz(str); } } char[] foo = "hello world"; Another a = new Another(foo[0 .. 5]); printf(a); //properly null-terminates How about it? :)
Jan 20 2004
In article <buksgm$1vc1$1 digitaldaemon.com>, Vathix says...Overloading an object to cast to another type: class Another { char[] str; this(char[] init) { str = init; } void opCast(out char* result) { result = toStringz(str); } } char[] foo = "hello world"; Another a = new Another(foo[0 .. 5]); printf(a); //properly null-terminates How about it? :)This seems so natural that it shouldn't even be a question! :-)
Jan 20 2004
wich is the same as operator Type() in c++, wich should be used in as less cases as possible. the implicit cast that happens can create such a ton of problems. nope. implicit casting should not be allowed "Georg Wrede" <Georg_member pathlink.com> schrieb im Newsbeitrag news:bulas9$2m2u$1 digitaldaemon.com...In article <buksgm$1vc1$1 digitaldaemon.com>, Vathix says...Overloading an object to cast to another type: class Another { char[] str; this(char[] init) { str = init; } void opCast(out char* result) { result = toStringz(str); } } char[] foo = "hello world"; Another a = new Another(foo[0 .. 5]); printf(a); //properly null-terminates How about it? :)This seems so natural that it shouldn't even be a question! :-)
Jan 20 2004
Wow! I hadn't looked at the example enough to realise that it was proposing implicit casting. No way, no how! "davepermen" <davepermen hotmail.com> wrote in message news:bulb6u$2mkc$1 digitaldaemon.com...wich is the same as operator Type() in c++, wich should be used in as less cases as possible. the implicit cast that happens can create such a ton of problems. nope. implicit casting should not be allowed "Georg Wrede" <Georg_member pathlink.com> schrieb im Newsbeitrag news:bulas9$2m2u$1 digitaldaemon.com...In article <buksgm$1vc1$1 digitaldaemon.com>, Vathix says...Overloading an object to cast to another type: class Another { char[] str; this(char[] init) { str = init; } void opCast(out char* result) { result = toStringz(str); } } char[] foo = "hello world"; Another a = new Another(foo[0 .. 5]); printf(a); //properly null-terminates How about it? :)This seems so natural that it shouldn't even be a question! :-)
Jan 21 2004
i think if cast(Type) will switch over to a template syntax, a.k.a. cast!(Type) we will soon write our own casts in that style.. just like static_cast!(Type) or similar.. any_cast!(Type), lexical_cast!(Type) etc.. this can be done even now yet.. so it's easy.. but we need type deduction actually.. uint x = 10; char[] str = "x = "; str ~= lexical_cast!(char[],uint)(x); hm.. if type deduction can not be implemented as is, i propose a new thing: typeof with the ? operator.. ?x is typeof(x) so we could at least write: uint x = 10; char[] str = "x = "; str ~= lexical_cast!(char[],?x)(x); of course, str ~= lexical_cast!(char[])(x); would be best.. "Matthew" <matthew.hat stlsoft.dot.org> schrieb im Newsbeitrag news:bulf2o$2u6r$1 digitaldaemon.com...Wow! I hadn't looked at the example enough to realise that it wasproposingimplicit casting. No way, no how! "davepermen" <davepermen hotmail.com> wrote in message news:bulb6u$2mkc$1 digitaldaemon.com...lesswich is the same as operator Type() in c++, wich should be used in asofcases as possible. the implicit cast that happens can create such a tonproblems. nope. implicit casting should not be allowed "Georg Wrede" <Georg_member pathlink.com> schrieb im Newsbeitrag news:bulas9$2m2u$1 digitaldaemon.com...In article <buksgm$1vc1$1 digitaldaemon.com>, Vathix says...Overloading an object to cast to another type: class Another { char[] str; this(char[] init) { str = init; } void opCast(out char* result) { result = toStringz(str); } } char[] foo = "hello world"; Another a = new Another(foo[0 .. 5]); printf(a); //properly null-terminates How about it? :)This seems so natural that it shouldn't even be a question! :-)
Jan 21 2004
Ok, I don't know enough about this to argue. But there really should be an easy way to use c and d strings in a mixed environment. Easy meaning less typing. In article <bulb6u$2mkc$1 digitaldaemon.com>, davepermen says...wich is the same as operator Type() in c++, wich should be used in as less cases as possible. the implicit cast that happens can create such a ton of problems. nope. implicit casting should not be allowed "Georg Wrede" <Georg_member pathlink.com> schrieb im Newsbeitrag news:bulas9$2m2u$1 digitaldaemon.com...In article <buksgm$1vc1$1 digitaldaemon.com>, Vathix says...Overloading an object to cast to another type: class Another { char[] str; this(char[] init) { str = init; } void opCast(out char* result) { result = toStringz(str); } } char[] foo = "hello world"; Another a = new Another(foo[0 .. 5]); printf(a); //properly null-terminates How about it? :)This seems so natural that it shouldn't even be a question! :-)
Jan 21 2004
davepermen wrote:wich is the same as operator Type() in c++, wich should be used in as less cases as possible. the implicit cast that happens can create such a ton of problems. nope. implicit casting should not be allowedImplicit casting is all right /so long as/ you distinguish between information-increasing casts and information-denuding casts; upcasts and downcasts. Casting from float to int is a downcast; we lose information. The opposite direction is an upcast; the new type has as much information or more (for the purposes of casting). With this information we can solve an equation's casting, handle explicit implicit casting, and generate cogent error messages in case of conflict, such as if there's a mutual upcast. C++ is a particular mess when it comes to this operator. There's no reversability, there's two ways to do one thing, it makes it impossible for implementations to produce a legible error report, and it treats a two-way street as if there's only one way you should want to go. Bloody awful. Don't judge a concept based on a broken implementation.
Jan 21 2004
i'm not sure. i don't really like it by default. i don't even use implicit casts if i code with integers and floats, just to make sure i code it really the way i want.. "Burton Radons" <loth users.sourceforge.net> schrieb im Newsbeitrag news:bunpiu$gtv$1 digitaldaemon.com...davepermen wrote:lesswich is the same as operator Type() in c++, wich should be used in asofcases as possible. the implicit cast that happens can create such a tonproblems. nope. implicit casting should not be allowedImplicit casting is all right /so long as/ you distinguish between information-increasing casts and information-denuding casts; upcasts and downcasts. Casting from float to int is a downcast; we lose information. The opposite direction is an upcast; the new type has as much information or more (for the purposes of casting). With this information we can solve an equation's casting, handle explicit implicit casting, and generate cogent error messages in case of conflict, such as if there's a mutual upcast. C++ is a particular mess when it comes to this operator. There's no reversability, there's two ways to do one thing, it makes it impossible for implementations to produce a legible error report, and it treats a two-way street as if there's only one way you should want to go. Bloody awful. Don't judge a concept based on a broken implementation.
Jan 22 2004
Vathix wrote:Overloading an object to cast to another type:I agree that we need something like that for symmetry. But to be used sparingly. In C++ we had explicit constructors. Maybe also opExplicitCast?class Another { char[] str; this(char[] init) { str = init; } void opCast(out char* result) { result = toStringz(str); }or even, let the return type be the type to cast to. char * opCast() { return toStringz(str); } Then i also have another idea. Some functions must be allowed to always implicitly cast their input, even if only explicit cast is defined for the input. Example: void sillyPrint(cast(char*) string) { /+...+/ } Now, given any type, for which explicit or implicit cast is defined, it would be implicitly cast to char* when fed to this function. -eye
Jan 23 2004
"Ilya Minkov" <minkov cs.tum.edu> wrote in message news:bus46u$1ljc$1 digitaldaemon.com...Vathix wrote:type opExplicitCast() is a good ideaOverloading an object to cast to another type:I agree that we need something like that for symmetry. But to be used sparingly. In C++ we had explicit constructors. Maybe also opExplicitCast?class Another { char[] str; this(char[] init) { str = init; } void opCast(out char* result) { result = toStringz(str); }or even, let the return type be the type to cast to. char * opCast() { return toStringz(str); }Then i also have another idea. Some functions must be allowed to always implicitly cast their input, even if only explicit cast is defined for the input. Example: void sillyPrint(cast(char*) string) { /+...+/ } Now, given any type, for which explicit or implicit cast is defined, it would be implicitly cast to char* when fed to this function.Nope. Explicit generalisation through shims (http://www.cuj.com/documents/s=8681/cuj0308wilson/) is a far better approach. It has all of the benefits, without any of the gotchas. Matthew P.S. btw, Ilya, did I tell you that the last chapter in the book is Properties, as inspired by your good self? :)
Jan 23 2004
Matthew wrote:type opExplicitCast() is a good ideaYup. If it doesn't complicate it for Walter too much.It may not be appropriate in all cases. A shim requieres explicit knowledge of the type to cast from - which may not be available for sillyPrint being a library function. I'm not sure i can recall in which case exactly it would really be very desirable, but i recall having had something on my mind a while ago... I know the conversion to char* is less than appropriate, and it was the reason why i called the function sillyPrint. ;) Luckily we have our char[], which contains length and can slice into any kind of string.Then i also have another idea. Some functions must be allowed to always implicitly cast their input, even if only explicit cast is defined for the input. Example: void sillyPrint(cast(char*) string) { /+...+/ } Now, given any type, for which explicit or implicit cast is defined, it would be implicitly cast to char* when fed to this function.Nope. Explicit generalisation through shims (http://www.cuj.com/documents/s=8681/cuj0308wilson/) is a far better approach. It has all of the benefits, without any of the gotchas.Matthew P.S. btw, Ilya, did I tell you that the last chapter in the book is Properties, as inspired by your good self? :)Yes, and it's one of the reasons i'm so eagerly awaiting the book! Btw, have you seen some Andy's experiment on the subject? http://ikagames.com/andy/property.h -eye
Jan 23 2004
Matthew wrote:I don't see how. (But then, I'm not a compiler-writer <g>)type opExplicitCast() is a good ideaYup. If it doesn't complicate it for Walter too much.I'm not sure if we're on the same page here. A shim is used to facilitate conversion between logically related, but physically unrelated, types. For example, we can define a functor (C++) that uses the c_str_ptr() shim: template <typename C> struct path_exists { public: template <typename S> bool operator ()(S const &file) const { return exists_(c_str_ptr(file)); } private: static bool exist_(C const *file) { . . . // OS test for file existence } }; and we can use this with *any* type for which the c_str_ptr() shim is valid. In STLSoft, there are shims defined for all manner of things, so you can use the above functor in containers of BSTR, VARIANT, LSA_UNICODE_STRING, basic_string<>, char *, wchar_t*, stlsoft::basic_simple_string<>, HWND, etc. etc. The important point is that there is unlimited generality, but because it is explicit - i.e. the path_exists functor contains a call to c_str_ptr() - there are no occasions where they can be called "by mistake" by the compiler. It's basically your classic win-win (apart from the odd hassle with Koenig lookup from dimwitted compilers)It may not be appropriate in all cases. A shim requieres explicit knowledge of the type to cast from - which may not be available for sillyPrint being a library function. I'm not sure i can recall in which case exactly it would really be very desirable, but i recall having had something on my mind a while ago...Then i also have another idea. Some functions must be allowed to always implicitly cast their input, even if only explicit cast is defined for the input. Example: void sillyPrint(cast(char*) string) { /+...+/ } Now, given any type, for which explicit or implicit cast is defined, it would be implicitly cast to char* when fed to this function.Nope. Explicit generalisation through shims (http://www.cuj.com/documents/s=8681/cuj0308wilson/) is a far better approach. It has all of the benefits, without any of the gotchas.I know the conversion to char* is less than appropriate, and it was the reason why i called the function sillyPrint. ;) Luckily we have our char[], which contains length and can slice into any kind of string.Good to hear! The properties templates will be released in STLSoft 1.7.1, which should be within the next 4-5 weeks, so they'll be available a few months before the book is. Also, it's likely that there'll be at least one article in CUJ on the subject around the middle of the year, probably just a few weeks before the book is launched.Matthew P.S. btw, Ilya, did I tell you that the last chapter in the book is Properties, as inspired by your good self? :)Yes, and it's one of the reasons i'm so eagerly awaiting the book! Btw, have you seen some Andy's experiment on the subject?http://ikagames.com/andy/property.hNo. I'll check it out. Does the implementation provide 100% speed efficiency, and 100% space efficiency for internally represented properties? Does it provide for field and method based properties? (Hopefully he's not stolen all my thunder <G>) Cheers Matthew P.S. I'm looking for volunteers for reviewing on the next book - taking some deep looks into STL - if anyone wants to volunteer. I understand if you don't, of course, as you may wish to save up your offers of service for the D book, which is the one after, if the current planning pans out. :)
Jan 23 2004
Hmm. It looks like this technique provides property-proxy objects, which one instantiates from a particular class instance, and which then provides property-like (get and/or set) access for the instance for which it acts. The Imperfect C++ / STLSoft properties are part of the classes for which they act; they're exactly as you'd expect from any other language which provides them as a built-in feature. (And they're stinkingly efficient! :)P.S. btw, Ilya, did I tell you that the last chapter in the book is Properties, as inspired by your good self? :)Yes, and it's one of the reasons i'm so eagerly awaiting the book! Btw, have you seen some Andy's experiment on the subject? http://ikagames.com/andy/property.h
Jan 23 2004
Ilya Minkov wrote: ...or even, let the return type be the type to cast to. char * opCast() { return toStringz(str); }I was going to suggest that first, but since you can't overload return values, I thought using an out parameter would be easier to implement.
Jan 23 2004
Vathix wrote:Whoops! My fault. You are right. In my background, return values cannot be discarded and thus overloads on return value are feasible. ;) But in D this doesn't hold true. -eyechar * opCast() { return toStringz(str); }I was going to suggest that first, but since you can't overload return values, I thought using an out parameter would be easier to implement.
Jan 24 2004