What exactly is or was the purpose of C++ function-style casts?
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);
}
Function-style cast vs. constructor
Syntactically, it is always a cast. That cast may happen to call a constructor:
char s [] = "Hello";
// Function-style cast; internally calls std::basic_string<char>::basic_string(char const*, Allocator)
std::string s2 = std::string(s);
// C-style cast; internally calls std::basic_string<char>::basic_string(char const*, Allocator)
std::string s3 = (std::string) s;
Is a C-style cast identical to a function-style cast?
I don't have a quote from the standard, but cppreference is usually good enough.
Explicit type conversion
The functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name:
unsigned int(expression)
orint*(expression)
are not valid), followed by a single expression in parentheses. This cast expression is exactly equivalent to the corresponding C-style cast expression.
As for Resharper, it's possible that to it C++ cast includes a functional cast, as that is only valid in C++.
The answer you linked in your question explains how safe a functional cast is. In your case int(d)
should be equivalent to static_cast<int>(d)
. But in general a C-style or functional cast are unsafe as they can be equivalent to reinterpret_cast
in certain situations, e.g. (double*)some_int_ptr
.
Function style casting vs calling constructor
It's a functional-style type conversion which creates a t
from an int
by calling the constructor. There is no way to explicitly call a constructor in C++.
This is described in [expr.type.conv]
(N3337):
5.2.3 Explicit type conversion (functional notation)
1) A simple-type-specifer (7.1.6.2) or typename-specifer (14.6) followed by a parenthesized expression-list
constructs a value of the specified type given the expression list. If the expression list is a single expression,
the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding
cast expression (5.4). If the type specified is a class type, the class type shall be complete. If the expression
list specifies more than a single value, the type shall be a class with a suitably declared constructor (8.5, 12.1),
and the expressionT(x1, x2, ...)
is equivalent in effect to the declarationT t(x1, x2, ...);
for some invented temporary variablet
, with the result being the value oft
as a prvalue.
Since t
is a simple-type-specifier, this is equivalent to the corresponding cast expression. This is allowed to carry out the equivalent of a static_cast
([expr.cast]/4
), which defines the final result of the conversion:
[expr.static.cast]/4:
Otherwise, an expressione
can be explicitly converted to a typeT
using astatic_cast
of the formstatic_cast<T>(e)
if the declarationT t(e);
is well-formed, for some invented temporary variablet
(8.5). The
effect of such an explicit conversion is the same as performing the declaration and initialization and then
using the temporary variable as the result of the conversion. The expressione
is used as a glvalue if and
only if the initialization uses it as a glvalue.
Why does C style cast allow you to convert to a private base class?
It's because in C it was allowed to convert any pointer to any other pointer using this cast and C++ tries to be C-compatible as much as possible, but tries to do a good job to be correct when it comes to classes, so C style cast is stronger than reinterpret_cast
in this situation.
What is the difference between static_cast and C style casting?
C++ style casts are checked by the compiler. C style casts aren't and can fail at runtime.
Also, c++ style casts can be searched for easily, whereas it's really hard to search for c style casts.
Another big benefit is that the 4 different C++ style casts express the intent of the programmer more clearly.
When writing C++ I'd pretty much always use the C++ ones over the the C style.
c++ difference between reinterpret cast and c style cast
reinterpret_cast
and const_cast
are ways of getting around the C++ type system. As you noted for reinterpret_cast
, this usually translates to little or no assembly code.
static_cast
mostly respects the C++ type system. It could convert a number from one type to another, or call a constructor, or call a conversion function. Or for a derived-to-base conversion, it might involve adding byte offsets and/or lookups into a vtable. static_cast
can also bend the type system's rules by "downcasting" a pointer or reference from a non-virtual base type to a derived type, possibly subtracting a byte offset.
And then there are pointers-to-member. They're probably beside the point here, but static_cast
does things to them more or less analogous to class pointer conversions.
dynamic_cast
respects the C++ type system even more strictly. In its useful form, it checks at runtime whether or not a pointer/reference actually points/refers to an object of the specified type. It typically calls a magic library function under the covers.
A function-style cast with one argument has exactly the same effect as a C-style cast. (With more than one argument, a function-style cast must be a temporary initialization using a class constructor.) A C-style cast does the first thing that makes sense out of the following list:
- a
const_cast
- a
static_cast
- a
static_cast
and then aconst_cast
- a
reinterpret_cast
, or - a
reinterpret_cast
and then aconst_cast
One exception: C-style casts can ignore private and protected inheritance relations between classes, pretending they have a public inheritance relation instead.
C-style casts are usually not preferred in C++ because it's less specific about what you want to happen.
Related Topics
How to Get the Application Data Path in Windows Using C++
Is It Bad Practice to Allocate Memory in a Dll and Give a Pointer to It to a Client App
C++ Comparison of Two Double Values Not Working Properly
How to Create a Temporary Directory in C++
Pointers to Members Representations
How to Show Enter Password in the Form of Asterisks(*) on Terminal
C++ Template Parameter Type Inference
Is-Braces-Constructible Type Trait
Removing Watermark Out of an Image Using Opencv
Why Must Const Members Be Initialized in the Constructor Initializer Rather Than in Its Body
How to Use a C++ Smart Pointers Together with C's Malloc
Convert a Unicode String in C++ to Upper Case
How to Extract the Mantissa of a Double
Get Sum of Values Stored in _M256D with Sse/Avx
Familiar Template Syntax for Generic Lambdas
Better Shading on Bw Display While Rendering Filled Surfaces