Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++, can we use { } for C-Style casting?

While I have been reading about datatype conversion, I saw this example:

void intval()
{
    for (char c; cin >> c; )
    cout << "the value of '" << c << "' is " << int{c} << '\n';
}

I know that we can cast using:

  1. int(c)
  2. (int) c
  3. static_cast<int>(c)

My questions:

Q1: Is int{c} another way of casting data types?

Q2: After some research on the net, I know that C++ casting is different and it have the compiler check the casting possibility at the compile time, but what are the differences between 1 and 2? And how int{c} is different if it is just another casting way?

Q3: Are there any other ways to explicitly convert/cast?

like image 505
Shadi Avatar asked Mar 23 '17 12:03

Shadi


People also ask

Can I use static_cast in C?

Static casts are only available in C++.

What is type casting in C or C++?

Type casting refers to the conversion of one data type to another in a program. Typecasting can be done in two ways: automatically by the compiler and manually by the programmer or user. Type Casting is also known as Type Conversion.

What does type casting C require?

Type Casting is basically a process in C in which we change a variable belonging to one data type to another one. In type casting, the compiler automatically changes one data type to another one depending on what we want the program to do.

Why is static_cast better than C-style cast?

In short: static_cast<>() gives you a compile time checking ability, C-Style cast doesn't. static_cast<>() is more readable and can be spotted easily anywhere inside a C++ source code, C_Style cast is'nt. Intentions are conveyed much better using C++ casts.


2 Answers

Is int{c} another way of casting data types?

Yes. T{value} creates a temporary of type T that is direct-list-initialized with the specified braced-init-list. This cast does have an advantage over T(value) in that T{value} can be used to create a temporary array. That would be done like

int main() {
    using int_array = int[5];
    for( auto e : int_array{1,2,3,4,5})
        std::cout << e;
}

It also comes with the caveat that a narrowing conversion is a error

int main() {
    int(10000000000ll);  // warning only, still compiles
    int{10000000000ll};  // hard error mandated by the standard
}

After some research on the net, I know that C++ casting is different and it have the compiler check the casting possibility at the compile time, but what are the differences between 1 and 2?

The big difference between T(value) and (T)value is that in T(value), T must be a single word. For example

int main() {
    unsigned int(10000000); // error
    (unsigned int)10000000; // compiles
}

Q3: Are there any other ways to explicitly convert/cast?

Well in C++ they want you to use the C++ casts which are static_cast, reinterpret_cast, dynamic_cast, and const_cast. Those are preferred over c style cast as a c style cast will do all of those where the C++ versions have certain limitations and come with certain guarantees.

like image 123
NathanOliver Avatar answered Nov 10 '22 02:11

NathanOliver


int(c) is the the C++ version of the C-style cast (int)c. It first attempts a const_cast<int>(c), then (failing that) a static_cast<int>(c) followed by reinterpret_cast.

int{c} is a slightly different kettle of fish. Strictly, this is list initialization and has more stringent rules. In particular, narrowing conversions are not allowed, i.e.

int x;
char s{x};  // error

Therefore, it is recommended to use this (rather than casts) unless you know that narrowing conversions are acceptable.

For other than builtin types, there is, in addition to the casts mentioned above, also dynamic_cast.

like image 45
Walter Avatar answered Nov 10 '22 03:11

Walter