Professional C__ - Marc Gregoire [146]
Type Aliases
C++11 adds a new mechanism for creating type aliases, which is easier to understand than the old typedefs in certain situations. It is called template aliases and allows you to give another name to specific type declarations. For example you could define a new name MyInt as an alias for int as follows:
using MyInt = int;
This is equivalent to the following old typedef syntax:
typedef int MyInt;
In both cases, you have given another name to type int and now you can define integers using type MyInt instead of int as follows:
MyInt i = 123;
Of course, the original type int still exists and can still be used as a type specification.
This new template alias feature is especially useful in cases where the typedef becomes complicated as is the case with typedefs for function pointers as seen in the previous section. For example, the following is the prototype of a function, which returns an integer and accepts a char and a double as parameters:
int someFunction(char c, double d);
If you would like to define a pointer pFunc to this function, you can do something like this:
int (*pFunc)(char, double) = &someFunction;
This is pretty hard to read. Before C++11 this could be simplified by using a typedef as explained in the previous section:
typedef int (*FuncType)(char, double);
FuncType pFunc = &someFunction;
The typedef defines a name FuncType, which specifies the type of a pointer to a function with the given prototype. Once this typedef is defined, using it is straightforward and easy to understand. However, the typedef line itself is convoluted because the name FuncType is somewhere in the middle of the line. Using the C++11 template alias feature this can be rewritten as follows:
using FuncType = int (*)(char, double);
FuncType pFunc = &someFunction;
This piece of code is doing exactly the same as the one using the typedef, but the using line is easier to read.
By reading through this section, you might think that the new template alias feature is nothing more than an easier-to-read typedef, but there is more. The problem with the old typedefs becomes apparent when you want to use it with templates, but that is covered in Chapter 19 because it requires more details about the template feature first.
Casts
The old-style C casts with () still work in C++. However, C++ also provides four new casts: static_cast, dynamic_cast, const_cast, and reinterpret_cast. You should use the C++ style casts instead of the old C-style casts because they perform more type checking and stand out better syntactically in your code.
This section describes the purposes for each cast and specifies when you would use each of them.
const_cast
The const_cast is the most straightforward. You can use it to cast away const-ness of a variable. It is the only cast of the four that is allowed to cast away const-ness. Theoretically, of course, there should be no need for a const cast. If a variable is const, it should stay const. In practice, however, you sometimes find yourself in a situation where a function is specified to take a const variable, which it must then pass to a function that takes a non-const variable. The “correct” solution would be to make const consistent in the program, but that is not always an option, especially if you are using third-party libraries. Thus, you sometimes need to cast away the const-ness of a variable. Here is an example:
extern void ThirdPartyLibraryMethod(char* str);
void f(const char* str)
{
ThirdPartyLibraryMethod(const_cast } Code snippet from Casts\ConstCast.cpp static_cast You can use the static_cast to perform explicitly conversions that are supported directly by the language. For example, if you write an arithmetic expression in which you need to convert an int to a double in order to avoid integer division, use a static_cast: int i = 3; double result = static_cast Code snippet from Casts\StaticCast.cpp You can also use static_cast to perform