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>()))> {};
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.
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.
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.
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.
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.
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.
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!!!!!!!
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.
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>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With