Outline
Purpose
Provide a mapping from integral constants to unique types.
Classes
- See also
Description
This component describes a simple class template, bsl::integral_constant
, that is used to map an integer constant to a C++ type. integral_constant<t_TYPE, t_VAL>
generates a unique type for each distinct compile-time integral t_TYPE
and constant integer t_VAL
parameter. That is, instantiations with different integer types and values form distinct types, so that integral_constant<int, 0>
is a different type from integral_constant<int, 1>
, which is also distinct from integral_constant<unsigned, 1>
, and so on. This mapping of integer values to types allows for "overloading by value", i.e., multiple functions with the same name can be overloaded on the "value" of an integral_constant
argument, provided that the value is known at compile-time. The typedefs bsl::true_type
and bsl::false_type
map the predicate values true
and false
to C++ types that are frequently useful for compile-time algorithms.
Usage
This section illustrates intended usage of this component
Example 1: Compile-Time Function Dispatching
The most common use of this structure is to perform compile-time function dispatching based on a compile-time calculation. Often the calculation is nothing more than a simple predicate, allowing us to select one of two functions based on whether the predicate holds. The following function, doSomething
, uses a fast implementation (e.g., using memcpy
) if the parameterized type allows for such operations, otherwise it will use a more generic and slower implementation (e.g., using the copy constructor). This example uses the types true_type
and false_type
, which are simple typedefs for integral_constant<bool, true>
and integral_constant<bool, false>
, respectively.
template <class t_T>
{
(void) t;
return 11;
}
template <class t_T>
{
(void) t;
return 55;
}
template <bool IsSlow, class t_T>
int doSomething(t_T *t)
{
}
For some parameter types, the fast version of doSomethingImp
is not legal. The power of this approach is that the compiler will not attempt semantic analysis on the implementation that does not match the appropriate integral_constant
argument.
int main()
{
int r;
int i;
r = doSomething<false>(&i);
assert(55 == r);
double m;
r = doSomething<true>(&m);
assert(11 == r);
return 0;
}
Example 2: Base Class For Metafunctions
Hard-coding the value of an integral_constant
is not especially useful. Rather, integral_constant
is typically used as the base class for "metafunction" classes, classes that yield the value of compile-time properties, including properties that are associated with types, rather than with values. For example, the following metafunction can be used at compile time to determine whether a type is a floating point type:
The value IsFloatingPoint<int>::value
is false and IsFloatingPoint<double>::value
is true. The integral_constant
base class has a member type, type
, that refers to itself and is inherited by IsFloatingPoint
. Thus IsFloatingPoint<float>::type
is true_type
and IsFloatingPoint<char>::type
is false_type
. IsFloatingPoint
is an a member of a common category of metafunctions known as "type traits" because they express certain properties (traits) of a type. Using this metafunction, we can rewrite the doSomething
function from first example so that it does not require the user to specify the IsSlow
template argument:
template <class t_T>
int doSomething2(t_T *t)
{
const bool isSlow = IsFloatingPoint<t_T>::value;
}
int main()
{
int r;
int i;
r = doSomething2(&i);
assert(55 == r);
double m;
r = doSomething2(&m);
assert(11 == r);
return 0;
}
◆ BSL_DEPRECATE_TRUE_FALSE_TYPE_VALUE
#define BSL_DEPRECATE_TRUE_FALSE_TYPE_VALUE |
Value:
"use standard, lower-case, 'value' instead")
#define BSLS_DEPRECATE_FEATURE(UOR, FEATURE, MESSAGE)
Definition bsls_deprecatefeature.h:319
◆ value [1/2]
template<class t_TYPE , t_TYPE t_VAL>
◆ value [2/2]
◆ VALUE