I am talking about \"type(value)\"-style casts. The books I have read pass over them quickly, saying only that they are semantically equivalent to C-style casts, \"(type) va
Function style casts bring consistency to primitive and user defined types. This is very useful when defining templates. For example, take this very silly example:
template<typename T, typename U>
T silly_cast(U const &u) {
return T(u);
}
My silly_cast function will work for primitive types, because it's a function-style cast. It will also work for user defined types, so long as class T has a single argument constructor that takes a U or U const &.
template<typename T, typename U>
T silly_cast(U const &u) {
return T(u);
}
class Foo {};
class Bar {
public:
Bar(Foo const&) {};
};
int main() {
long lg = 1L;
Foo f;
int v = silly_cast<int>(lg);
Bar b = silly_cast<Bar>(f);
}
What book was this??? It's the C-style casts which are generally thought to be a bad idea. Most modern C++ code looks like this (when a cast is needed)
x = sometype( y );
rather than
x = (sometype) y;
Apart from anything else, the former syntax looks much more like a constructor call, which in most cases it probably is, though the two forms are actually semantically identical.
C-style casts should not be used.
Function-style casts should be used, especially when the target type is a class name (or class template specialization). They fit the pattern of apparent constructor calls in the case with one argument.
MyClass( expr ); // Creates temporary, initialized like MyClass obj( expr );
MyClass( e1, e2 ); // Similar, and no other way to write this.
int( expr ); // Function-style cast.
The purpose of them is so you could pass more than one argument to a class' constructor:
T(a1, a2); // call 2-argument constructor
(T)(a1, a2); // would only pass a2.
There is no mechanism that the (T) expr style cast would be able to pass multiple arguments, so a new form of conversion was needed. It's natural to define (T) expr as a degenerate case of T(expr).
Contrary to what some people here say, (T) expr works exactly like T(expr), so it will work just fine with class types too.
It is somewhat easier to parse the function-style casts in a language where parentheses are already heavily (over-)used.
Were they a mistake? Possibly - but only to the extent that they were unable to completely supersede the C-style casts, and therefore provided a Perl-like "there's more than one way to do it" mechanism for casting. With the explicit and distinctive modern casts:
dynamic_cast<type>(value);
reinterpret_cast<type>(value);
static_cast<type>(value);
const_cast<type>(value);
there is no reason to use the C-style casts any more, and less reason to use function-style casts.
AFAIK function-style casts are an extension to native types of the usual syntax of temporary creation for classes: as long as you can create a temporary object inside an expression using the syntax ClassName(parameters), there's no reason why you shouldn't do that with native types. edit Notice that, as @steve said, this is very useful in templates
Notice that one-parameter constructors in C++ are often somehow "felt" as conversion facilities, see for example the syntax (conversion constructor) that allows you to initialize a new object using an equal sign followed by a value
ClassName MyObject = 3;
which actually means
ClassName MyObject(3);
and (presumably) calls the one-int-parameter constructor of ClassName.
By the way, here's a nice page about function-style casts.