BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslmf_unwraprefdecay

Detailed Description

Provide a meta-function to decay and unwrap reference wrappers.

Outline

Purpose

Provide a meta-function to decay and unwrap reference wrappers.

Classes

Canonical Header

bsl_functional.h, bsl_type_traits.h

See also
bslmf_referencewrapper, bslmf_unwrap_reference

Description

This component defines a meta-function bsl::unwrap_ref_decay that may be used to unwrap a possibly cv-qualified bsl::reference_wrapper (which is an alias of std::reference_wrapper if that exists) specialization or reference thereto of some type U, resulting in U&. In case the specified type template argument is not a specialization of bsl::reference_wrapper the result is the type, but decayed (bsl::decay).

bsl::unwrap_ref_decay meets the requirements of the unwrap_ref_decay template defined in the C++20 standard [meta.trans.other].

Usage

In this section we show intended use of this component.

Example 1: Unwrap Reference Wrapped Argument Types

Suppose that we work in a programming environment where function argument types may be presented as is, or wrapped in a bsl::reference_wrapper and we would like to create a member or local variable while obeying the request for the reference type that the reference-wrapper represents. As parameters may be cv-qualified and may be references we need to first decay them (see bsl::decay). When the argument type decays into a reference-wrapper we want to use a reference to the wrapped type, and simply use the decayed variations of types that are not wrapped. This is a use case for bsl::unwrap_ref_decay.

First, we create types that may be the bases for reference-wrapped, and normal type parameters:

typedef bsl::reference_wrapper<int *> WrappedType;
typedef int *NotWrappedType;
Definition bslmf_referencewrapper.h:182

Next, we create types that represent possible function argument types:

typedef WrappedType WrappedTypeArray[5];
typedef WrappedType *WrappedTypePointer;
typedef const WrappedType ConstWrappedType;
typedef volatile WrappedType VolatileWrappedType;
typedef const volatile WrappedType CvWrappedType;
typedef WrappedType& WrappedTypeRef;
typedef const WrappedType& ConstWrappedTypeRef;
typedef volatile WrappedType& VolatileWrappedTypeRef;
typedef const volatile WrappedType& CvWrappedTypeRef;
typedef NotWrappedType NotWrappedTypeArray[5];
typedef NotWrappedType *NotWrappedTypePointer;
typedef const NotWrappedType ConstNotWrappedType;
typedef volatile NotWrappedType VolatileNotWrappedType;
typedef const volatile NotWrappedType CvNotWrappedType;
typedef NotWrappedType& NotWrappedTypeRef;
typedef const NotWrappedType& ConstNotWrappedTypeRef;
typedef volatile NotWrappedType& VolatileNotWrappedTypeRef;
typedef const volatile NotWrappedType& CvNotWrappedTypeRef;

Finally we can verify and demonstrate how all these types turn into a decayed type, and only those that decay into a reference-wrapper type will become themselves references. Notice that an array of reference wrappers decays into a pointer to a wrapper, so it will not turn into a reference.

assert((true == bsl::is_same<bsl::unwrap_ref_decay<WrappedTypeArray>::type,
WrappedType *>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<WrappedTypePointer>::type,
WrappedTypePointer>::value));
assert((true == bsl::is_same<bsl::unwrap_ref_decay<WrappedType>::type,
int *&>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<ConstWrappedType>::type,
int *&>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<VolatileWrappedType>::type,
int *&>::value));
assert((true == bsl::is_same<bsl::unwrap_ref_decay<CvWrappedType>::type,
int *&>::value));
assert((true == bsl::is_same<bsl::unwrap_ref_decay<WrappedTypeRef>::type,
int *&>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<ConstWrappedTypeRef>::type,
int *&>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<VolatileWrappedTypeRef>::type,
int *&>::value));
assert((true == bsl::is_same<bsl::unwrap_ref_decay<CvWrappedTypeRef>::type,
int *&>::value));
// Not wrapped types decay
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<NotWrappedTypeArray>::type,
NotWrappedType *>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<NotWrappedTypePointer>::type,
NotWrappedTypePointer>::value));
assert((true == bsl::is_same<bsl::unwrap_ref_decay<NotWrappedType>::type,
NotWrappedType>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<ConstNotWrappedType>::type,
NotWrappedType>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<VolatileNotWrappedType>::type,
NotWrappedType>::value));
assert((true == bsl::is_same<bsl::unwrap_ref_decay<CvNotWrappedType>::type,
NotWrappedType>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<NotWrappedTypeRef>::type,
NotWrappedType>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<ConstNotWrappedTypeRef>::type,
NotWrappedType>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<VolatileNotWrappedTypeRef>::type,
NotWrappedType>::value));
assert((true == bsl::is_same<
bsl::unwrap_ref_decay<CvNotWrappedTypeRef>::type,
NotWrappedType>::value));
Definition bslmf_issame.h:146

Note, that (when available) the bsl::unwrap_ref_decay_t avoids the ::type suffix and typename prefix when we want to use the result of the bsl::unwrap_ref_decay meta-function in templates.