Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is static_cast needed in the gcc's implementation of is_nothrow_constructible?

Taken from the GCC implementation of type_traits why is static_cast needed here?

template <typename _Tp, typename... _Args>
struct __is_nt_constructible_impl
    : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))> {};

template <typename _Tp, typename _Arg>
struct __is_nt_constructible_impl<_Tp, _Arg>
    : public integral_constant<bool,
                               // Why is `static_cast` needed here?
                               noexcept(static_cast<_Tp>(declval<_Arg>()))> {};
like image 285
João Pires Avatar asked Jan 07 '20 11:01

João Pires


People also ask

Why do we use static_cast?

The static_cast is used for the normal/ordinary type conversion. This is also the cast responsible for implicit type coercion and can also be called explicitly. You should use it in cases like converting float to int, char to int, etc. This can cast related type classes.

How is static_cast implemented?

static_cast is always resolved using compile-time type info. (This may involve a runtime action). If it's not an appropriate cast you either get a compile error or undefined behaviour. In your snippet it is OK because b is a D ; however if b were new B() then the cast compiles but causes undefined behaviour if run.

What static_cast is actually doing?

In short, static_cast<> will try to convert, e.g., float-to-integer, while reinterpret_cast<> simply changes the compiler's mind to reconsider that object as another type.

Should I use static_cast?

You shouldn't use static_cast for casting down an inheritance hierarchy, but rather dynamic_cast . That will return either the null pointer or a valid pointer.

What is static_cast in C++?

static_cast in C++ | Type Casting operators. A Cast operator is an unary operator which forces one data type to be converted into another data type. C++ supports four types of casting: 1. Static Cast. 2. Dynamic Cast. 3. Const Cast. 4. Reinterpret Cast.

What is the difference between C-style cast and static cast?

In contrast to the C-style cast, the static cast will allow the compiler to check that the pointer and pointee data types are compatible, which allows the programmer to catch this incorrect pointer assignment during compilation. I disagree that static_cast<> () is more readable.

Does static_cast perform a tight type checking?

As we know static_cast performs a tight type checking, let’s the changed code slightly to see it: Try to compile the above code, What do you see?? Compilation Error!!!!!!!

What is the use of cast in C++?

This is also the cast responsible for implicit type coercion and can also be called explicitly. You should use it in cases like converting float to int, char to int, etc. This can cast related type classes. If the types are not same it will generate some error.


1 Answers

A type is nothrow constructible from an argument list if the invented variable declaration

T t(declval<Args>()...);

would be well-formed and is known not to throw exceptions. In the plural argument case this is equivalent (modulo noexcept destructibility, see LWG 2116) to the well-formedness and nothrow of the type conversion expression

T(declval<Args>()...)

However in the single argument case the expression T(declval<Args>()) is treated as a cast-expression, which can invoke const_cast and reinterpret_cast; the explicit use of static_cast restores the equivalence to the declaration form.

As a concrete example, consider the types:

struct D;
struct B { operator D&&() const; };
struct D : B {};

Here a static_cast from B const to D&& must use the conversion operator, but a cast expression can bypass the conversion operator and so is noexcept. So omitting the static_cast would give the wrong result for is_nothrow_constructible<D&&, B const>.

like image 132
ecatmur Avatar answered Oct 29 '22 12:10

ecatmur