简体   繁体   中英

What exactly is or was the purpose of C++ function-style casts?

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) value", and that they should be avoided. If they mean the same thing an old-style cast does, why were they ever added to the language? Also, because declarations can contain superfluous parentheses, this code: "T x(T(y));" doesn't do what someone intending to use the function-style casts would expect; it declares a function named x accepting a T and returning a T rather than constructing a T variable named x by casting y to a T.

Were they a mistake in the design of the language?

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);
}

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.

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.

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 'sa nice page about function-style casts.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM