|
BDE 4.14.0 Production release
|
Macros | |
| #define | BSLMF_TYPEIDENTITY_T(...) typename ::bsl::type_identity<__VA_ARGS__ >::type |
Provide a template metafunction that returns its argument.
bsl::type_identity_t for C++03This component provides a trivial template metafunction class, bsl::type_identity that takes one type template argument and produces the argument type as its result; i.e., bsl::type_identity<t_TYPE>::type is simply an alias for t_TYPE. This metafunction is used in situations where a no-op metafunction is desired or where template type deduction should be suppressed. This component also provides, for C++11 and later, an alias, bsl::type_identity_t such that bsl::type_identity_t<t_TYPE> is short hand for typename bsl::type_identity<t_TYPE>::type.
The templates in this component have identical functionality to the standard templates, std::type_identity and std::type_identity_t defined in the <type_traits> header starting with C++20.
A function template can often deduce the types of its arguments, but sometimes we wish to prevent such deduction and require the user to supply the desired type explicitly. In this example, we'll declare a cast function, implicitCast, that is invoked implicitCast<T>(arg). The goal is cast the arg to type T, but only if arg is implicitly convertible to T.
First, we'll define a type TestType, that is implicitly convertible from int but only explicitly convertible from const char *:
Next, we'll define implicitCastNAIVE, a naive and insufficient attempt at defining implicitCast:
Next, we try to use implicitCastNAIVE. The first invocation below correctly casts an int to TestType. The second invocation should, and does, fail to compile because const char* is not implicitly convertible to TestType. In the third invocation, we forgot the <TestType> template parameter. Surprisingly (for the user), the code compiles anyway because implicitCastNAIVE deduced t_TYPE to be const char* and returns its argument unmodified, i.e., doing no casting whatsoever:
Now, we implement implicitCast correctly, using bsl::type_identity to prevent implicit template-argument deduction:
Finally, we try using implicitCast both correctly and incorrectly. As before, the first invocation below correctly casts an int to TestType and second invocation correctly fails to compile. Unlike the implicitCastNAIVE example, however, the third invocation correctly fails to compile because t_TYPE is not deduceable for a parameter of type bsl::type_identity<t_TYPE>::type.
Note that typename bsl::type_identity<t_TYPE>::type can be replaced by the more concise bsl::type_identity_t<t_TYPE> (compatible with C++11 and later) or BSLMF_TYPEIDENTITY_T(t_TYPE) (compatible with all C++ versions).
In this example, we illustrate how to prevent ambiguities when type deductions occurs on multiple function-template arguments. Our sample function returns a number within a range two-thirds of the way between the start and end of the range. The types of the arguments determine the type of the result.
First, we implement the function using a simple but potentially ambiguous interface:
Now, try to invoke our function. We get into trouble when the two arguments have different types; the compiler is unable to deduce a single NUMTYPE:
Next, we try again, this time using bsl::type_identity to suppress type deduction on the first argument. The first argument, rather than the second argument is chosen for this treatment because the first argument of a numeric range is so often 0, which happens to be an int but is often used, without losing precision, with unsigned, float, and double values. The second argument, conversely, usually carries a significant value whose type is important:
Finally, we verify that our twoThirdsOfTheWay function worked correctly:
| #define BSLMF_TYPEIDENTITY_T | ( | ... | ) | typename ::bsl::type_identity<__VA_ARGS__ >::type |
Metafunction returning its type argument unchanged. Shorthand alias for typename type_identity<...>::type. The type argument to this macro must be a dependent type of the function template or class template in which it is used, i.e., a template parameter or type related to a template parameter. Note that this macro exists for compatibility with C++03; for C++11 and later compilers, bsl::type_identity_t is preferred.
Implementation note: space before closing > is important to avoid >> issues in C++03.