Prev: The D Programming Language
Next: CRTP question
From: Terry G on 23 Nov 2006 23:01 > This is not meant to pick on you. But, I don't want to generic code like > that. And I would not want C++ programmers to get exposed to that kind > of code as the sort of things people write in generic programmng :-) > I would like to write a generic format() that does not require a cast > (whether static or not). Someone has to convert bits to higher level constructs. Generic programming is valuable for that. Casts are unavoidable for this, no? terry -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Clark S. Cox III on 24 Nov 2006 04:14 Terry G wrote: >> Terry G ha scritto: >>> A question: why do you prefer static_cast<value_type>(val) >>> instead of using the function-like form: value_type(val)? >>> Is there any significant difference? >>> >> Ganesh replied >> The function-like form with one argument is actually equivalent to the >> C-style cast (value_type)(val) so it could apply either a static_cast or >> a reinterpret_cast (plus an additional const_cast). > > Terry had a spaz! > > What!? I thought the function-style cast was equivalent to static_cast. > I read the C++ spec and its not yet clear to me. > It seems that for built-in types, type(x) is equivalent to (type) x. > That's > scary. > But what about for non-built-in types. Is type(x) equivalent to > static_cast<type>(x)? > Should I stop using function-style casts altogether? "type(x)" casts are always equivalent to "(type)x" casts. >From "5.2.3 Explicit type conversion (functional notation)": A simple-type-specifier (7.1.5) followed by a parenthesized expression-list constructs a value of the specified type given the expression list. If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4). "5.4 Explicit type conversion (cast notation)" describes the "(type)x" style casts. -- Clark S. Cox III clarkcox3(a)gmail.com [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Gabriel Dos Reis on 24 Nov 2006 04:14 "Terry G" <tjgolubi(a)netins.net> writes: | > This is not meant to pick on you. But, I don't want to generic code like | > that. And I would not want C++ programmers to get exposed to that kind | > of code as the sort of things people write in generic programmng :-) | > I would like to write a generic format() that does not require a cast | > (whether static or not). | | Someone has to convert bits to higher level constructs. | Generic programming is valuable for that. So is conventional procedural programming :-) | Casts are unavoidable for this, no? The code shown used a static_cast, not a reinterpret_cast -- so in fact, it was restricting the space of allowed casts; it isn't "generic" if I may say. The question therefore is why the static_cast is better than simple *it = val; -- Gabriel Dos Reis gdr(a)integrable-solutions.net [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: James Kanze on 24 Nov 2006 04:24 Terry G wrote: > > Terry G ha scritto: > >> A question: why do you prefer static_cast<value_type>(val) > >> instead of using the function-like form: value_type(val)? > >> Is there any significant difference? > > Ganesh replied > > The function-like form with one argument is actually equivalent to the > > C-style cast (value_type)(val) so it could apply either a static_cast or > > a reinterpret_cast (plus an additional const_cast). > Terry had a spaz! > What!? I thought the function-style cast was equivalent to static_cast. > I read the C++ spec and its not yet clear to me. �5.2.3/2 (Explicit type conversion (functional notation): "If the expression list is a single expression, the type conversion expression is equivalent (in de- finedness, and if defined in meaning) to the corresponding cast expression (5.4)." And in �5.4/5: The conversions performed by -- a const_cast (5.2.11), -- a static_cast (5.2.9), -- a static_cast followed by a const_cast, -- a reinterpret_cast (5.2.10), or -- a reinterpret_cast followed by a const_cast, can be performed using the cast notation of explicit type conversion. [...] If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used[...] > It seems that for built-in types, type(x) is equivalent to > (type) x. That's scary. > But what about for non-built-in types. Is type(x) equivalent to > static_cast<type>(x)? The differences always involve references and/or pointers, I think---all reinterpret_cast have either a reference or a pointer as either the target type or the source type. But when casting between pointer types or reference types, you have to be exceedingly careful: struct Base1 {} ; struct Base2 {} ; struct Derived : Base1, Base2 {} ; typedef Base1* B1Ptr ; typedef Base2* B2Ptr ; typedef Derived* DPtr ; B1Ptr pB1 ; B2Ptr pB2 ; DPtr pD ; pB1 = B1Ptr( pD ) ; // static_cast pB2 = B2Ptr( pD ) ; // static_cast pD = DPtr( pB1 ) ; // static_cast pD = DPtr( pB2 ) ; // static_cast pB1 = B1Ptr( pB2 ) ; // reinterpret_cast pB2 = B2Ptr( pB1 ) ; // reinterpret_cast > Should I stop using function-style casts altogether? It's a style question. I (and I suspect most people) use them rather freely when converting to a class type; the syntax is parallel to that used when constructing with more than one argument, or with no arguments. I tend to use C style casts when converting between arithmetic types, or when converting a class (which has a user defined conversion operator) to an arithmetic type, but I'm not necessarily systematic about it; I'll sometimes use a static_cast as well. I will never use anything but static_cast (or reinterpret_cast, if that's what I want) when pointers or references are involved on either side of the cast. (And I don't typedef pointers or references, so that it is always clear when this is the case.) -- James Kanze (GABI Software) email:james.kanze(a)gmail.com Conseils en informatique orient�e objet/ Beratung in objektorientierter Datenverarbeitung 9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34 -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Alberto Ganesh Barbati on 24 Nov 2006 05:44
Terry G ha scritto: >> Terry G ha scritto: >>> A question: why do you prefer static_cast<value_type>(val) >>> instead of using the function-like form: value_type(val)? >>> Is there any significant difference? >>> >> Ganesh replied >> The function-like form with one argument is actually equivalent to the >> C-style cast (value_type)(val) so it could apply either a static_cast or >> a reinterpret_cast (plus an additional const_cast). > > Terry had a spaz! I had it too, when they told me the first time. > What!? I thought the function-style cast was equivalent to static_cast. > I read the C++ spec and its not yet clear to me. > It seems that for built-in types, type(x) is equivalent to (type) x. > That's scary. > But what about for non-built-in types. Is type(x) equivalent to > static_cast<type>(x)? 5.2.3/1 does not mention built-in types, so it applies to all types: "If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4)." However, reinterpret_cast can only perform the conversions listed in 5.2.10, in particular it can't convert anything to a user defined type T unless T is a reference type. Notice that the only way to write a conversion to a reference type using function-style syntax is by using a typedef and that rarely happens in non-generic code. > Should I stop using function-style casts altogether? If the target type is a non-pointer, non-reference UDT or a floating point type, then it's safe to use, because neither reinterpret_cast nor const_cast will apply in those cases. Ditto for integral types unless the source type is a pointer type. If the target type is either a pointer type (any kind, including pointers to members) or a reference type or if there's any chance that it might be so (for example in generic code) then I would avoid the function-style in favor of an explicit use of either static_cast or reinterpret_cast. Ganesh -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |